• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test.h"
12 
13 #include <sstream>
14 
15 #include "webrtc/base/arraysize.h"
16 #include "webrtc/base/common.h"
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/modules/include/module_common_types.h"
19 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
20 #include "webrtc/modules/remote_bitrate_estimator/test/metric_recorder.h"
21 #include "webrtc/modules/remote_bitrate_estimator/test/packet_receiver.h"
22 #include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h"
23 #include "webrtc/system_wrappers/include/clock.h"
24 #include "webrtc/test/testsupport/perf_test.h"
25 
26 using std::string;
27 using std::vector;
28 
29 namespace webrtc {
30 namespace testing {
31 namespace bwe {
32 
PacketProcessorRunner(PacketProcessor * processor)33 PacketProcessorRunner::PacketProcessorRunner(PacketProcessor* processor)
34     : processor_(processor) {
35 }
36 
~PacketProcessorRunner()37 PacketProcessorRunner::~PacketProcessorRunner() {
38   for (Packet* packet : queue_)
39     delete packet;
40 }
41 
RunsProcessor(const PacketProcessor * processor) const42 bool PacketProcessorRunner::RunsProcessor(
43     const PacketProcessor* processor) const {
44   return processor == processor_;
45 }
46 
RunFor(int64_t time_ms,int64_t time_now_ms,Packets * in_out)47 void PacketProcessorRunner::RunFor(int64_t time_ms,
48                                    int64_t time_now_ms,
49                                    Packets* in_out) {
50   Packets to_process;
51   FindPacketsToProcess(processor_->flow_ids(), in_out, &to_process);
52   processor_->RunFor(time_ms, &to_process);
53   QueuePackets(&to_process, time_now_ms * 1000);
54   if (!to_process.empty()) {
55     processor_->Plot(to_process.back()->send_time_ms());
56   }
57   in_out->merge(to_process, DereferencingComparator<Packet>);
58 }
59 
FindPacketsToProcess(const FlowIds & flow_ids,Packets * in,Packets * out)60 void PacketProcessorRunner::FindPacketsToProcess(const FlowIds& flow_ids,
61                                                  Packets* in,
62                                                  Packets* out) {
63   assert(out->empty());
64   for (Packets::iterator it = in->begin(); it != in->end();) {
65     // TODO(holmer): Further optimize this by looking for consecutive flow ids
66     // in the packet list and only doing the binary search + splice once for a
67     // sequence.
68     if (flow_ids.find((*it)->flow_id()) != flow_ids.end()) {
69       Packets::iterator next = it;
70       ++next;
71       out->splice(out->end(), *in, it);
72       it = next;
73     } else {
74       ++it;
75     }
76   }
77 }
78 
QueuePackets(Packets * batch,int64_t end_of_batch_time_us)79 void PacketProcessorRunner::QueuePackets(Packets* batch,
80                                          int64_t end_of_batch_time_us) {
81   queue_.merge(*batch, DereferencingComparator<Packet>);
82   if (queue_.empty()) {
83     return;
84   }
85   Packets::iterator it = queue_.begin();
86   for (; it != queue_.end(); ++it) {
87     if ((*it)->send_time_us() > end_of_batch_time_us) {
88       break;
89     }
90   }
91   Packets to_transfer;
92   to_transfer.splice(to_transfer.begin(), queue_, queue_.begin(), it);
93   batch->merge(to_transfer, DereferencingComparator<Packet>);
94 }
95 
96 // Plot link capacity by default.
BweTest()97 BweTest::BweTest() : BweTest(true) {
98 }
99 
BweTest(bool plot_capacity)100 BweTest::BweTest(bool plot_capacity)
101     : run_time_ms_(0),
102       time_now_ms_(-1),
103       simulation_interval_ms_(-1),
104       plot_total_available_capacity_(plot_capacity) {
105   links_.push_back(&uplink_);
106   links_.push_back(&downlink_);
107 }
108 
~BweTest()109 BweTest::~BweTest() {
110   for (Packet* packet : packets_)
111     delete packet;
112 }
113 
SetUp()114 void BweTest::SetUp() {
115   const ::testing::TestInfo* const test_info =
116       ::testing::UnitTest::GetInstance()->current_test_info();
117   string test_name =
118       string(test_info->test_case_name()) + "_" + string(test_info->name());
119   BWE_TEST_LOGGING_GLOBAL_CONTEXT(test_name);
120   BWE_TEST_LOGGING_GLOBAL_ENABLE(false);
121 }
122 
AddPacketProcessor(PacketProcessor * processor,ProcessorType processor_type)123 void Link::AddPacketProcessor(PacketProcessor* processor,
124                               ProcessorType processor_type) {
125   assert(processor);
126   switch (processor_type) {
127     case kSender:
128       senders_.push_back(static_cast<PacketSender*>(processor));
129       break;
130     case kReceiver:
131       receivers_.push_back(static_cast<PacketReceiver*>(processor));
132       break;
133     case kRegular:
134       break;
135   }
136   processors_.push_back(PacketProcessorRunner(processor));
137 }
138 
RemovePacketProcessor(PacketProcessor * processor)139 void Link::RemovePacketProcessor(PacketProcessor* processor) {
140   for (vector<PacketProcessorRunner>::iterator it = processors_.begin();
141        it != processors_.end(); ++it) {
142     if (it->RunsProcessor(processor)) {
143       processors_.erase(it);
144       return;
145     }
146   }
147   assert(false);
148 }
149 
150 // Ownership of the created packets is handed over to the caller.
Run(int64_t run_for_ms,int64_t now_ms,Packets * packets)151 void Link::Run(int64_t run_for_ms, int64_t now_ms, Packets* packets) {
152   for (auto& processor : processors_) {
153     processor.RunFor(run_for_ms, now_ms, packets);
154   }
155 }
156 
VerboseLogging(bool enable)157 void BweTest::VerboseLogging(bool enable) {
158   BWE_TEST_LOGGING_GLOBAL_ENABLE(enable);
159 }
160 
RunFor(int64_t time_ms)161 void BweTest::RunFor(int64_t time_ms) {
162   // Set simulation interval from first packet sender.
163   // TODO(holmer): Support different feedback intervals for different flows.
164   if (!uplink_.senders().empty()) {
165     simulation_interval_ms_ = uplink_.senders()[0]->GetFeedbackIntervalMs();
166   } else if (!downlink_.senders().empty()) {
167     simulation_interval_ms_ = downlink_.senders()[0]->GetFeedbackIntervalMs();
168   }
169   assert(simulation_interval_ms_ > 0);
170   if (time_now_ms_ == -1) {
171     time_now_ms_ = simulation_interval_ms_;
172   }
173   for (run_time_ms_ += time_ms;
174        time_now_ms_ <= run_time_ms_ - simulation_interval_ms_;
175        time_now_ms_ += simulation_interval_ms_) {
176     // Packets are first generated on the first link, passed through all the
177     // PacketProcessors and PacketReceivers. The PacketReceivers produces
178     // FeedbackPackets which are then processed by the next link, where they
179     // at some point will be consumed by a PacketSender.
180     for (Link* link : links_)
181       link->Run(simulation_interval_ms_, time_now_ms_, &packets_);
182   }
183 }
184 
GetTestName() const185 string BweTest::GetTestName() const {
186   const ::testing::TestInfo* const test_info =
187       ::testing::UnitTest::GetInstance()->current_test_info();
188   return string(test_info->name());
189 }
190 
PrintResults(double max_throughput_kbps,Stats<double> throughput_kbps,int flow_id,Stats<double> flow_delay_ms,Stats<double> flow_throughput_kbps)191 void BweTest::PrintResults(double max_throughput_kbps,
192                            Stats<double> throughput_kbps,
193                            int flow_id,
194                            Stats<double> flow_delay_ms,
195                            Stats<double> flow_throughput_kbps) {
196   std::map<int, Stats<double>> flow_delays_ms;
197   flow_delays_ms[flow_id] = flow_delay_ms;
198   std::map<int, Stats<double>> flow_throughputs_kbps;
199   flow_throughputs_kbps[flow_id] = flow_throughput_kbps;
200   PrintResults(max_throughput_kbps, throughput_kbps, flow_delays_ms,
201                flow_throughputs_kbps);
202 }
203 
PrintResults(double max_throughput_kbps,Stats<double> throughput_kbps,std::map<int,Stats<double>> flow_delay_ms,std::map<int,Stats<double>> flow_throughput_kbps)204 void BweTest::PrintResults(double max_throughput_kbps,
205                            Stats<double> throughput_kbps,
206                            std::map<int, Stats<double>> flow_delay_ms,
207                            std::map<int, Stats<double>> flow_throughput_kbps) {
208   double utilization = throughput_kbps.GetMean() / max_throughput_kbps;
209   webrtc::test::PrintResult("BwePerformance", GetTestName(), "Utilization",
210                             utilization * 100.0, "%", false);
211   std::stringstream ss;
212   ss << throughput_kbps.GetStdDev() / throughput_kbps.GetMean();
213   webrtc::test::PrintResult("BwePerformance", GetTestName(),
214                             "Utilization var coeff", ss.str(), "", false);
215   for (auto& kv : flow_throughput_kbps) {
216     ss.str("");
217     ss << "Throughput flow " << kv.first;
218     webrtc::test::PrintResultMeanAndError("BwePerformance", GetTestName(),
219                                           ss.str(), kv.second.AsString(),
220                                           "kbps", false);
221   }
222   for (auto& kv : flow_delay_ms) {
223     ss.str("");
224     ss << "Delay flow " << kv.first;
225     webrtc::test::PrintResultMeanAndError("BwePerformance", GetTestName(),
226                                           ss.str(), kv.second.AsString(), "ms",
227                                           false);
228   }
229   double fairness_index = 1.0;
230   if (!flow_throughput_kbps.empty()) {
231     double squared_bitrate_sum = 0.0;
232     fairness_index = 0.0;
233     for (auto kv : flow_throughput_kbps) {
234       squared_bitrate_sum += kv.second.GetMean() * kv.second.GetMean();
235       fairness_index += kv.second.GetMean();
236     }
237     fairness_index *= fairness_index;
238     fairness_index /= flow_throughput_kbps.size() * squared_bitrate_sum;
239   }
240   webrtc::test::PrintResult("BwePerformance", GetTestName(), "Fairness",
241                             fairness_index * 100, "%", false);
242 }
243 
RunFairnessTest(BandwidthEstimatorType bwe_type,size_t num_media_flows,size_t num_tcp_flows,int64_t run_time_seconds,uint32_t capacity_kbps,int64_t max_delay_ms,int64_t rtt_ms,int64_t max_jitter_ms,const int64_t * offsets_ms)244 void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type,
245                               size_t num_media_flows,
246                               size_t num_tcp_flows,
247                               int64_t run_time_seconds,
248                               uint32_t capacity_kbps,
249                               int64_t max_delay_ms,
250                               int64_t rtt_ms,
251                               int64_t max_jitter_ms,
252                               const int64_t* offsets_ms) {
253   RunFairnessTest(bwe_type, num_media_flows, num_tcp_flows, run_time_seconds,
254                   capacity_kbps, max_delay_ms, rtt_ms, max_jitter_ms,
255                   offsets_ms, "Fairness_test", bwe_names[bwe_type]);
256 }
257 
RunFairnessTest(BandwidthEstimatorType bwe_type,size_t num_media_flows,size_t num_tcp_flows,int64_t run_time_seconds,uint32_t capacity_kbps,int64_t max_delay_ms,int64_t rtt_ms,int64_t max_jitter_ms,const int64_t * offsets_ms,const std::string & title,const std::string & flow_name)258 void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type,
259                               size_t num_media_flows,
260                               size_t num_tcp_flows,
261                               int64_t run_time_seconds,
262                               uint32_t capacity_kbps,
263                               int64_t max_delay_ms,
264                               int64_t rtt_ms,
265                               int64_t max_jitter_ms,
266                               const int64_t* offsets_ms,
267                               const std::string& title,
268                               const std::string& flow_name) {
269   std::set<int> all_flow_ids;
270   std::set<int> media_flow_ids;
271   std::set<int> tcp_flow_ids;
272   int next_flow_id = 0;
273   for (size_t i = 0; i < num_media_flows; ++i) {
274     media_flow_ids.insert(next_flow_id);
275     all_flow_ids.insert(next_flow_id);
276     ++next_flow_id;
277   }
278   for (size_t i = 0; i < num_tcp_flows; ++i) {
279     tcp_flow_ids.insert(next_flow_id);
280     all_flow_ids.insert(next_flow_id);
281     ++next_flow_id;
282   }
283 
284   std::vector<VideoSource*> sources;
285   std::vector<PacketSender*> senders;
286   std::vector<MetricRecorder*> metric_recorders;
287 
288   int64_t max_offset_ms = 0;
289 
290   for (int media_flow : media_flow_ids) {
291     sources.push_back(new AdaptiveVideoSource(media_flow, 30, 300, 0,
292                                               offsets_ms[media_flow]));
293     senders.push_back(new PacedVideoSender(&uplink_, sources.back(), bwe_type));
294     max_offset_ms = std::max(max_offset_ms, offsets_ms[media_flow]);
295   }
296 
297   for (int tcp_flow : tcp_flow_ids) {
298     senders.push_back(new TcpSender(&uplink_, tcp_flow, offsets_ms[tcp_flow]));
299     max_offset_ms = std::max(max_offset_ms, offsets_ms[tcp_flow]);
300   }
301 
302   ChokeFilter choke(&uplink_, all_flow_ids);
303   choke.set_capacity_kbps(capacity_kbps);
304   choke.set_max_delay_ms(max_delay_ms);
305   LinkShare link_share(&choke);
306 
307   int64_t one_way_delay_ms = rtt_ms / 2;
308   DelayFilter delay_uplink(&uplink_, all_flow_ids);
309   delay_uplink.SetOneWayDelayMs(one_way_delay_ms);
310 
311   JitterFilter jitter(&uplink_, all_flow_ids);
312   jitter.SetMaxJitter(max_jitter_ms);
313 
314   std::vector<RateCounterFilter*> rate_counters;
315   for (int flow : media_flow_ids) {
316     rate_counters.push_back(
317         new RateCounterFilter(&uplink_, flow, "Receiver", bwe_names[bwe_type]));
318   }
319   for (int flow : tcp_flow_ids) {
320     rate_counters.push_back(new RateCounterFilter(&uplink_, flow, "Receiver",
321                                                   bwe_names[kTcpEstimator]));
322   }
323 
324   RateCounterFilter total_utilization(
325       &uplink_, all_flow_ids, "total_utilization", "Total_link_utilization");
326 
327   std::vector<PacketReceiver*> receivers;
328   // Delays is being plotted only for the first flow.
329   // To plot all of them, replace "i == 0" with "true" on new PacketReceiver().
330   for (int media_flow : media_flow_ids) {
331     metric_recorders.push_back(
332         new MetricRecorder(bwe_names[bwe_type], static_cast<int>(media_flow),
333                            senders[media_flow], &link_share));
334     receivers.push_back(new PacketReceiver(&uplink_, media_flow, bwe_type,
335                                            media_flow == 0, false,
336                                            metric_recorders[media_flow]));
337     metric_recorders[media_flow]->set_plot_available_capacity(
338         media_flow == 0 && plot_total_available_capacity_);
339     metric_recorders[media_flow]->set_start_computing_metrics_ms(max_offset_ms);
340   }
341   // Delays is not being plotted only for TCP flows. To plot all of them,
342   // replace first "false" occurence with "true" on new PacketReceiver().
343   for (int tcp_flow : tcp_flow_ids) {
344     metric_recorders.push_back(
345         new MetricRecorder(bwe_names[kTcpEstimator], static_cast<int>(tcp_flow),
346                            senders[tcp_flow], &link_share));
347     receivers.push_back(new PacketReceiver(&uplink_, tcp_flow, kTcpEstimator,
348                                            false, false,
349                                            metric_recorders[tcp_flow]));
350     metric_recorders[tcp_flow]->set_plot_available_capacity(
351         tcp_flow == 0 && plot_total_available_capacity_);
352   }
353 
354   DelayFilter delay_downlink(&downlink_, all_flow_ids);
355   delay_downlink.SetOneWayDelayMs(one_way_delay_ms);
356 
357   RunFor(run_time_seconds * 1000);
358 
359   std::map<int, Stats<double>> flow_throughput_kbps;
360   for (RateCounterFilter* rate_counter : rate_counters) {
361     int flow_id = *rate_counter->flow_ids().begin();
362     flow_throughput_kbps[flow_id] = rate_counter->GetBitrateStats();
363   }
364 
365   std::map<int, Stats<double>> flow_delay_ms;
366   for (PacketReceiver* receiver : receivers) {
367     int flow_id = *receiver->flow_ids().begin();
368     flow_delay_ms[flow_id] = receiver->GetDelayStats();
369   }
370 
371   PrintResults(capacity_kbps, total_utilization.GetBitrateStats(),
372                flow_delay_ms, flow_throughput_kbps);
373 
374   for (int i : all_flow_ids) {
375     metric_recorders[i]->PlotThroughputHistogram(
376         title, flow_name, static_cast<int>(num_media_flows), 0);
377 
378     metric_recorders[i]->PlotLossHistogram(title, flow_name,
379                                            static_cast<int>(num_media_flows),
380                                            receivers[i]->GlobalPacketLoss());
381   }
382 
383   // Pointless to show delay histogram for TCP flow.
384   for (int i : media_flow_ids) {
385     metric_recorders[i]->PlotDelayHistogram(title, bwe_names[bwe_type],
386                                             static_cast<int>(num_media_flows),
387                                             one_way_delay_ms);
388     BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], one_way_delay_ms, i);
389   }
390 
391   for (VideoSource* source : sources)
392     delete source;
393   for (PacketSender* sender : senders)
394     delete sender;
395   for (RateCounterFilter* rate_counter : rate_counters)
396     delete rate_counter;
397   for (PacketReceiver* receiver : receivers)
398     delete receiver;
399   for (MetricRecorder* recorder : metric_recorders)
400     delete recorder;
401 }
402 
RunChoke(BandwidthEstimatorType bwe_type,std::vector<int> capacities_kbps)403 void BweTest::RunChoke(BandwidthEstimatorType bwe_type,
404                        std::vector<int> capacities_kbps) {
405   int flow_id = bwe_type;
406   AdaptiveVideoSource source(flow_id, 30, 300, 0, 0);
407   VideoSender sender(&uplink_, &source, bwe_type);
408   ChokeFilter choke(&uplink_, flow_id);
409   LinkShare link_share(&choke);
410   MetricRecorder metric_recorder(bwe_names[bwe_type], flow_id, &sender,
411                                  &link_share);
412   PacketReceiver receiver(&uplink_, flow_id, bwe_type, true, false,
413                           &metric_recorder);
414   metric_recorder.set_plot_available_capacity(plot_total_available_capacity_);
415 
416   choke.set_max_delay_ms(500);
417   const int64_t kRunTimeMs = 60 * 1000;
418 
419   std::stringstream title("Choke");
420   char delimiter = '_';
421 
422   for (auto it = capacities_kbps.begin(); it != capacities_kbps.end(); ++it) {
423     choke.set_capacity_kbps(*it);
424     RunFor(kRunTimeMs);
425     title << delimiter << (*it);
426     delimiter = '-';
427   }
428 
429   title << "_kbps,_" << (kRunTimeMs / 1000) << "s_each";
430   metric_recorder.PlotThroughputHistogram(title.str(), bwe_names[bwe_type], 1,
431                                           0);
432   metric_recorder.PlotDelayHistogram(title.str(), bwe_names[bwe_type], 1, 0);
433   // receiver.PlotLossHistogram(title, bwe_names[bwe_type], 1);
434   // receiver.PlotObjectiveHistogram(title, bwe_names[bwe_type], 1);
435 }
436 
437 // 5.1. Single Video and Audio media traffic, forward direction.
RunVariableCapacity1SingleFlow(BandwidthEstimatorType bwe_type)438 void BweTest::RunVariableCapacity1SingleFlow(BandwidthEstimatorType bwe_type) {
439   const int kFlowId = 0;  // Arbitrary value.
440   AdaptiveVideoSource source(kFlowId, 30, 300, 0, 0);
441   PacedVideoSender sender(&uplink_, &source, bwe_type);
442 
443   DefaultEvaluationFilter up_filter(&uplink_, kFlowId);
444   LinkShare link_share(&(up_filter.choke));
445   MetricRecorder metric_recorder(bwe_names[bwe_type], kFlowId, &sender,
446                                  &link_share);
447 
448   PacketReceiver receiver(&uplink_, kFlowId, bwe_type, true, true,
449                           &metric_recorder);
450 
451   metric_recorder.set_plot_available_capacity(plot_total_available_capacity_);
452 
453   DelayFilter down_filter(&downlink_, kFlowId);
454   down_filter.SetOneWayDelayMs(kOneWayDelayMs);
455 
456   // Test also with one way propagation delay = 100ms.
457   // up_filter.delay.SetOneWayDelayMs(100);
458   // down_filter.SetOneWayDelayMs(100);
459 
460   up_filter.choke.set_capacity_kbps(1000);
461   RunFor(40 * 1000);  // 0-40s.
462   up_filter.choke.set_capacity_kbps(2500);
463   RunFor(20 * 1000);  // 40-60s.
464   up_filter.choke.set_capacity_kbps(600);
465   RunFor(20 * 1000);  // 60-80s.
466   up_filter.choke.set_capacity_kbps(1000);
467   RunFor(20 * 1000);  // 80-100s.
468 
469   std::string title("5.1_Variable_capacity_single_flow");
470   metric_recorder.PlotThroughputHistogram(title, bwe_names[bwe_type], 1, 0);
471   metric_recorder.PlotDelayHistogram(title, bwe_names[bwe_type], 1,
472                                      kOneWayDelayMs);
473   metric_recorder.PlotLossHistogram(title, bwe_names[bwe_type], 1,
474                                     receiver.GlobalPacketLoss());
475   BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, kFlowId);
476 }
477 
478 // 5.2. Two forward direction competing flows, variable capacity.
RunVariableCapacity2MultipleFlows(BandwidthEstimatorType bwe_type,size_t num_flows)479 void BweTest::RunVariableCapacity2MultipleFlows(BandwidthEstimatorType bwe_type,
480                                                 size_t num_flows) {
481   std::vector<VideoSource*> sources;
482   std::vector<PacketSender*> senders;
483   std::vector<MetricRecorder*> metric_recorders;
484   std::vector<PacketReceiver*> receivers;
485 
486   const int64_t kStartingApartMs = 0;  // Flows initialized simultaneously.
487 
488   for (size_t i = 0; i < num_flows; ++i) {
489     sources.push_back(new AdaptiveVideoSource(static_cast<int>(i), 30, 300, 0,
490                                               i * kStartingApartMs));
491     senders.push_back(new VideoSender(&uplink_, sources[i], bwe_type));
492   }
493 
494   FlowIds flow_ids = CreateFlowIdRange(0, static_cast<int>(num_flows - 1));
495 
496   DefaultEvaluationFilter up_filter(&uplink_, flow_ids);
497   LinkShare link_share(&(up_filter.choke));
498 
499   RateCounterFilter total_utilization(&uplink_, flow_ids, "Total_utilization",
500                                       "Total_link_utilization");
501 
502   // Delays is being plotted only for the first flow.
503   // To plot all of them, replace "i == 0" with "true" on new PacketReceiver().
504   for (size_t i = 0; i < num_flows; ++i) {
505     metric_recorders.push_back(new MetricRecorder(
506         bwe_names[bwe_type], static_cast<int>(i), senders[i], &link_share));
507 
508     receivers.push_back(new PacketReceiver(&uplink_, static_cast<int>(i),
509                                            bwe_type, i == 0, false,
510                                            metric_recorders[i]));
511     metric_recorders[i]->set_plot_available_capacity(
512         i == 0 && plot_total_available_capacity_);
513   }
514 
515   DelayFilter down_filter(&downlink_, flow_ids);
516   down_filter.SetOneWayDelayMs(kOneWayDelayMs);
517   // Test also with one way propagation delay = 100ms.
518   // up_filter.delay.SetOneWayDelayMs(100);
519   // down_filter.SetOneWayDelayMs(100);
520 
521   up_filter.choke.set_capacity_kbps(4000);
522   RunFor(25 * 1000);  // 0-25s.
523   up_filter.choke.set_capacity_kbps(2000);
524   RunFor(25 * 1000);  // 25-50s.
525   up_filter.choke.set_capacity_kbps(3500);
526   RunFor(25 * 1000);  // 50-75s.
527   up_filter.choke.set_capacity_kbps(1000);
528   RunFor(25 * 1000);  // 75-100s.
529   up_filter.choke.set_capacity_kbps(2000);
530   RunFor(25 * 1000);  // 100-125s.
531 
532   std::string title("5.2_Variable_capacity_two_flows");
533   for (size_t i = 0; i < num_flows; ++i) {
534     metric_recorders[i]->PlotThroughputHistogram(title, bwe_names[bwe_type],
535                                                  num_flows, 0);
536     metric_recorders[i]->PlotDelayHistogram(title, bwe_names[bwe_type],
537                                             num_flows, kOneWayDelayMs);
538     metric_recorders[i]->PlotLossHistogram(title, bwe_names[bwe_type],
539                                            num_flows,
540                                            receivers[i]->GlobalPacketLoss());
541     BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i);
542   }
543 
544   for (VideoSource* source : sources)
545     delete source;
546   for (PacketSender* sender : senders)
547     delete sender;
548   for (MetricRecorder* recorder : metric_recorders)
549     delete recorder;
550   for (PacketReceiver* receiver : receivers)
551     delete receiver;
552 }
553 
554 // 5.3. Bi-directional RMCAT flows.
RunBidirectionalFlow(BandwidthEstimatorType bwe_type)555 void BweTest::RunBidirectionalFlow(BandwidthEstimatorType bwe_type) {
556   enum direction { kForward = 0, kBackward };
557   const size_t kNumFlows = 2;
558   rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows];
559   rtc::scoped_ptr<VideoSender> senders[kNumFlows];
560   rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows];
561   rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows];
562 
563   sources[kForward].reset(new AdaptiveVideoSource(kForward, 30, 300, 0, 0));
564   senders[kForward].reset(
565       new VideoSender(&uplink_, sources[kForward].get(), bwe_type));
566 
567   sources[kBackward].reset(new AdaptiveVideoSource(kBackward, 30, 300, 0, 0));
568   senders[kBackward].reset(
569       new VideoSender(&downlink_, sources[kBackward].get(), bwe_type));
570 
571   DefaultEvaluationFilter up_filter(&uplink_, kForward);
572   LinkShare up_link_share(&(up_filter.choke));
573 
574   metric_recorders[kForward].reset(new MetricRecorder(
575       bwe_names[bwe_type], kForward, senders[kForward].get(), &up_link_share));
576   receivers[kForward].reset(
577       new PacketReceiver(&uplink_, kForward, bwe_type, true, false,
578                          metric_recorders[kForward].get()));
579 
580   metric_recorders[kForward].get()->set_plot_available_capacity(
581       plot_total_available_capacity_);
582 
583   DefaultEvaluationFilter down_filter(&downlink_, kBackward);
584   LinkShare down_link_share(&(down_filter.choke));
585 
586   metric_recorders[kBackward].reset(
587       new MetricRecorder(bwe_names[bwe_type], kBackward,
588                          senders[kBackward].get(), &down_link_share));
589   receivers[kBackward].reset(
590       new PacketReceiver(&downlink_, kBackward, bwe_type, true, false,
591                          metric_recorders[kBackward].get()));
592 
593   metric_recorders[kBackward].get()->set_plot_available_capacity(
594       plot_total_available_capacity_);
595 
596   // Test also with one way propagation delay = 100ms.
597   // up_filter.delay.SetOneWayDelayMs(100);
598   // down_filter.delay.SetOneWayDelayMs(100);
599 
600   up_filter.choke.set_capacity_kbps(2000);
601   down_filter.choke.set_capacity_kbps(2000);
602   RunFor(20 * 1000);  // 0-20s.
603 
604   up_filter.choke.set_capacity_kbps(1000);
605   RunFor(15 * 1000);  // 20-35s.
606 
607   down_filter.choke.set_capacity_kbps(800);
608   RunFor(5 * 1000);  // 35-40s.
609 
610   up_filter.choke.set_capacity_kbps(500);
611   RunFor(20 * 1000);  // 40-60s.
612 
613   up_filter.choke.set_capacity_kbps(2000);
614   RunFor(10 * 1000);  // 60-70s.
615 
616   down_filter.choke.set_capacity_kbps(2000);
617   RunFor(30 * 1000);  // 70-100s.
618 
619   std::string title("5.3_Bidirectional_flows");
620   for (size_t i = 0; i < kNumFlows; ++i) {
621     metric_recorders[i].get()->PlotThroughputHistogram(
622         title, bwe_names[bwe_type], kNumFlows, 0);
623     metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type],
624                                                   kNumFlows, kOneWayDelayMs);
625     metric_recorders[i].get()->PlotLossHistogram(
626         title, bwe_names[bwe_type], kNumFlows,
627         receivers[i].get()->GlobalPacketLoss());
628     BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i);
629   }
630 }
631 
632 // 5.4. Three forward direction competing flows, constant capacity.
RunSelfFairness(BandwidthEstimatorType bwe_type)633 void BweTest::RunSelfFairness(BandwidthEstimatorType bwe_type) {
634   const int kNumRmcatFlows = 3;
635   const int kNumTcpFlows = 0;
636   const int64_t kRunTimeS = 120;
637   const int kLinkCapacity = 3500;
638 
639   int64_t max_delay_ms = kMaxQueueingDelayMs;
640   int64_t rtt_ms = 2 * kOneWayDelayMs;
641 
642   const int64_t kStartingApartMs = 20 * 1000;
643   int64_t offsets_ms[kNumRmcatFlows];
644   for (int i = 0; i < kNumRmcatFlows; ++i) {
645     offsets_ms[i] = kStartingApartMs * i;
646   }
647 
648   // Test also with one way propagation delay = 100ms.
649   // rtt_ms = 2 * 100;
650   // Test also with bottleneck queue size = 20ms and 1000ms.
651   // max_delay_ms = 20;
652   // max_delay_ms = 1000;
653 
654   std::string title("5.4_Self_fairness_test");
655 
656   // Test also with one way propagation delay = 100ms.
657   RunFairnessTest(bwe_type, kNumRmcatFlows, kNumTcpFlows, kRunTimeS,
658                   kLinkCapacity, max_delay_ms, rtt_ms, kMaxJitterMs, offsets_ms,
659                   title, bwe_names[bwe_type]);
660 }
661 
662 // 5.5. Five competing RMCAT flows under different RTTs.
RunRoundTripTimeFairness(BandwidthEstimatorType bwe_type)663 void BweTest::RunRoundTripTimeFairness(BandwidthEstimatorType bwe_type) {
664   const int kAllFlowIds[] = {0, 1, 2, 3, 4};  // Five RMCAT flows.
665   const int64_t kAllOneWayDelayMs[] = {10, 25, 50, 100, 150};
666   const size_t kNumFlows = arraysize(kAllFlowIds);
667   rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows];
668   rtc::scoped_ptr<VideoSender> senders[kNumFlows];
669   rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows];
670 
671   // Flows initialized 10 seconds apart.
672   const int64_t kStartingApartMs = 10 * 1000;
673 
674   for (size_t i = 0; i < kNumFlows; ++i) {
675     sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0,
676                                              i * kStartingApartMs));
677     senders[i].reset(new VideoSender(&uplink_, sources[i].get(), bwe_type));
678   }
679 
680   ChokeFilter choke_filter(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
681   LinkShare link_share(&choke_filter);
682 
683   JitterFilter jitter_filter(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
684 
685   rtc::scoped_ptr<DelayFilter> up_delay_filters[kNumFlows];
686   for (size_t i = 0; i < kNumFlows; ++i) {
687     up_delay_filters[i].reset(new DelayFilter(&uplink_, kAllFlowIds[i]));
688   }
689 
690   RateCounterFilter total_utilization(
691       &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "Total_utilization",
692       "Total_link_utilization");
693 
694   // Delays is being plotted only for the first flow.
695   // To plot all of them, replace "i == 0" with "true" on new PacketReceiver().
696   rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows];
697   for (size_t i = 0; i < kNumFlows; ++i) {
698     metric_recorders[i].reset(
699         new MetricRecorder(bwe_names[bwe_type], static_cast<int>(i),
700                            senders[i].get(), &link_share));
701 
702     receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], bwe_type,
703                                           i == 0, false,
704                                           metric_recorders[i].get()));
705     metric_recorders[i].get()->set_start_computing_metrics_ms(kStartingApartMs *
706                                                               (kNumFlows - 1));
707     metric_recorders[i].get()->set_plot_available_capacity(
708         i == 0 && plot_total_available_capacity_);
709   }
710 
711   rtc::scoped_ptr<DelayFilter> down_delay_filters[kNumFlows];
712   for (size_t i = 0; i < kNumFlows; ++i) {
713     down_delay_filters[i].reset(new DelayFilter(&downlink_, kAllFlowIds[i]));
714   }
715 
716   jitter_filter.SetMaxJitter(kMaxJitterMs);
717   choke_filter.set_max_delay_ms(kMaxQueueingDelayMs);
718 
719   for (size_t i = 0; i < kNumFlows; ++i) {
720     up_delay_filters[i]->SetOneWayDelayMs(kAllOneWayDelayMs[i]);
721     down_delay_filters[i]->SetOneWayDelayMs(kAllOneWayDelayMs[i]);
722   }
723 
724   choke_filter.set_capacity_kbps(3500);
725 
726   RunFor(300 * 1000);  // 0-300s.
727 
728   std::string title("5.5_Round_Trip_Time_Fairness");
729   for (size_t i = 0; i < kNumFlows; ++i) {
730     metric_recorders[i].get()->PlotThroughputHistogram(
731         title, bwe_names[bwe_type], kNumFlows, 0);
732     metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type],
733                                                   kNumFlows, kOneWayDelayMs);
734     metric_recorders[i].get()->PlotLossHistogram(
735         title, bwe_names[bwe_type], kNumFlows,
736         receivers[i].get()->GlobalPacketLoss());
737     BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kAllOneWayDelayMs[i],
738                                  i);
739   }
740 }
741 
742 // 5.6. RMCAT Flow competing with a long TCP Flow.
RunLongTcpFairness(BandwidthEstimatorType bwe_type)743 void BweTest::RunLongTcpFairness(BandwidthEstimatorType bwe_type) {
744   const size_t kNumRmcatFlows = 1;
745   const size_t kNumTcpFlows = 1;
746   const int64_t kRunTimeS = 120;
747   const int kCapacityKbps = 2000;
748   // Tcp starts at t = 0, media flow at t = 5s.
749   const int64_t kOffSetsMs[] = {5000, 0};
750 
751   int64_t max_delay_ms = kMaxQueueingDelayMs;
752   int64_t rtt_ms = 2 * kOneWayDelayMs;
753 
754   // Test also with one way propagation delay = 100ms.
755   // rtt_ms = 2 * 100;
756   // Test also with bottleneck queue size = 20ms and 1000ms.
757   // max_delay_ms = 20;
758   // max_delay_ms = 1000;
759 
760   std::string title("5.6_Long_TCP_Fairness");
761   std::string flow_name(bwe_names[bwe_type] + 'x' + bwe_names[kTcpEstimator]);
762 
763   RunFairnessTest(bwe_type, kNumRmcatFlows, kNumTcpFlows, kRunTimeS,
764                   kCapacityKbps, max_delay_ms, rtt_ms, kMaxJitterMs, kOffSetsMs,
765                   title, flow_name);
766 }
767 
768 // 5.7. RMCAT Flows competing with multiple short TCP Flows.
RunMultipleShortTcpFairness(BandwidthEstimatorType bwe_type,std::vector<int> tcp_file_sizes_bytes,std::vector<int64_t> tcp_starting_times_ms)769 void BweTest::RunMultipleShortTcpFairness(
770     BandwidthEstimatorType bwe_type,
771     std::vector<int> tcp_file_sizes_bytes,
772     std::vector<int64_t> tcp_starting_times_ms) {
773   // Two RMCAT flows and ten TCP flows.
774   const int kAllRmcatFlowIds[] = {0, 1};
775   const int kAllTcpFlowIds[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
776 
777   assert(tcp_starting_times_ms.size() == tcp_file_sizes_bytes.size() &&
778          tcp_starting_times_ms.size() == arraysize(kAllTcpFlowIds));
779 
780   const size_t kNumRmcatFlows = arraysize(kAllRmcatFlowIds);
781   const size_t kNumTotalFlows = kNumRmcatFlows + arraysize(kAllTcpFlowIds);
782 
783   rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumRmcatFlows];
784   rtc::scoped_ptr<PacketSender> senders[kNumTotalFlows];
785   rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumTotalFlows];
786   rtc::scoped_ptr<PacketReceiver> receivers[kNumTotalFlows];
787 
788   // RMCAT Flows are initialized simultaneosly at t=5 seconds.
789   const int64_t kRmcatStartingTimeMs = 5 * 1000;
790   for (size_t id : kAllRmcatFlowIds) {
791     sources[id].reset(new AdaptiveVideoSource(static_cast<int>(id), 30, 300, 0,
792                                               kRmcatStartingTimeMs));
793     senders[id].reset(new VideoSender(&uplink_, sources[id].get(), bwe_type));
794   }
795 
796   for (size_t id : kAllTcpFlowIds) {
797     senders[id].reset(new TcpSender(&uplink_, static_cast<int>(id),
798                                     tcp_starting_times_ms[id - kNumRmcatFlows],
799                                     tcp_file_sizes_bytes[id - kNumRmcatFlows]));
800   }
801 
802   FlowIds flow_ids = CreateFlowIdRange(0, static_cast<int>(kNumTotalFlows - 1));
803   DefaultEvaluationFilter up_filter(&uplink_, flow_ids);
804 
805   LinkShare link_share(&(up_filter.choke));
806 
807   RateCounterFilter total_utilization(&uplink_, flow_ids, "Total_utilization",
808                                       "Total_link_utilization");
809 
810   // Delays is being plotted only for the first flow.
811   // To plot all of them, replace "i == 0" with "true" on new PacketReceiver().
812   for (size_t id : kAllRmcatFlowIds) {
813     metric_recorders[id].reset(
814         new MetricRecorder(bwe_names[bwe_type], static_cast<int>(id),
815                            senders[id].get(), &link_share));
816     receivers[id].reset(new PacketReceiver(&uplink_, static_cast<int>(id),
817                                            bwe_type, id == 0, false,
818                                            metric_recorders[id].get()));
819     metric_recorders[id].get()->set_start_computing_metrics_ms(
820         kRmcatStartingTimeMs);
821     metric_recorders[id].get()->set_plot_available_capacity(
822         id == 0 && plot_total_available_capacity_);
823   }
824 
825   // Delays is not being plotted only for TCP flows. To plot all of them,
826   // replace first "false" occurence with "true" on new PacketReceiver().
827   for (size_t id : kAllTcpFlowIds) {
828     metric_recorders[id].reset(
829         new MetricRecorder(bwe_names[kTcpEstimator], static_cast<int>(id),
830                            senders[id].get(), &link_share));
831     receivers[id].reset(new PacketReceiver(&uplink_, static_cast<int>(id),
832                                            kTcpEstimator, false, false,
833                                            metric_recorders[id].get()));
834     metric_recorders[id].get()->set_plot_available_capacity(
835         id == 0 && plot_total_available_capacity_);
836   }
837 
838   DelayFilter down_filter(&downlink_, flow_ids);
839   down_filter.SetOneWayDelayMs(kOneWayDelayMs);
840 
841   // Test also with one way propagation delay = 100ms.
842   // up_filter.delay.SetOneWayDelayMs(100);
843   // down_filter.SetOneWayDelayms(100);
844 
845   // Test also with bottleneck queue size = 20ms and 1000ms.
846   // up_filter.choke.set_max_delay_ms(20);
847   // up_filter.choke.set_max_delay_ms(1000);
848 
849   // Test also with no Jitter:
850   // up_filter.jitter.SetMaxJitter(0);
851 
852   up_filter.choke.set_capacity_kbps(2000);
853 
854   RunFor(300 * 1000);  // 0-300s.
855 
856   std::string title("5.7_Multiple_short_TCP_flows");
857   for (size_t id : kAllRmcatFlowIds) {
858     metric_recorders[id].get()->PlotThroughputHistogram(
859         title, bwe_names[bwe_type], kNumRmcatFlows, 0);
860     metric_recorders[id].get()->PlotDelayHistogram(
861         title, bwe_names[bwe_type], kNumRmcatFlows, kOneWayDelayMs);
862     metric_recorders[id].get()->PlotLossHistogram(
863         title, bwe_names[bwe_type], kNumRmcatFlows,
864         receivers[id].get()->GlobalPacketLoss());
865     BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, id);
866   }
867 }
868 
869 // 5.8. Three forward direction competing flows, constant capacity.
870 // During the test, one of the flows is paused and later resumed.
RunPauseResumeFlows(BandwidthEstimatorType bwe_type)871 void BweTest::RunPauseResumeFlows(BandwidthEstimatorType bwe_type) {
872   const int kAllFlowIds[] = {0, 1, 2};  // Three RMCAT flows.
873   const size_t kNumFlows = arraysize(kAllFlowIds);
874 
875   rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows];
876   rtc::scoped_ptr<VideoSender> senders[kNumFlows];
877   rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows];
878   rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows];
879 
880   // Flows initialized simultaneously.
881   const int64_t kStartingApartMs = 0;
882 
883   for (size_t i = 0; i < kNumFlows; ++i) {
884     sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0,
885                                              i * kStartingApartMs));
886     senders[i].reset(new VideoSender(&uplink_, sources[i].get(), bwe_type));
887   }
888 
889   DefaultEvaluationFilter filter(&uplink_,
890                                  CreateFlowIds(kAllFlowIds, kNumFlows));
891 
892   LinkShare link_share(&(filter.choke));
893 
894   RateCounterFilter total_utilization(
895       &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "Total_utilization",
896       "Total_link_utilization");
897 
898   // Delays is being plotted only for the first flow.
899   // To plot all of them, replace "i == 0" with "true" on new PacketReceiver().
900   for (size_t i = 0; i < kNumFlows; ++i) {
901     metric_recorders[i].reset(
902         new MetricRecorder(bwe_names[bwe_type], static_cast<int>(i),
903                            senders[i].get(), &link_share));
904     receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], bwe_type,
905                                           i == 0, false,
906                                           metric_recorders[i].get()));
907     metric_recorders[i].get()->set_start_computing_metrics_ms(kStartingApartMs *
908                                                               (kNumFlows - 1));
909     metric_recorders[i].get()->set_plot_available_capacity(
910         i == 0 && plot_total_available_capacity_);
911   }
912 
913   // Test also with one way propagation delay = 100ms.
914   // filter.delay.SetOneWayDelayMs(100);
915   filter.choke.set_capacity_kbps(3500);
916 
917   RunFor(40 * 1000);  // 0-40s.
918   senders[0].get()->Pause();
919   RunFor(20 * 1000);  // 40-60s.
920   senders[0].get()->Resume(20 * 1000);
921   RunFor(60 * 1000);  // 60-120s.
922 
923   int64_t paused[] = {20 * 1000, 0, 0};
924 
925   // First flow is being paused, hence having a different optimum.
926   const std::string optima_lines[] = {"1", "2", "2"};
927 
928   std::string title("5.8_Pause_and_resume_media_flow");
929   for (size_t i = 0; i < kNumFlows; ++i) {
930     metric_recorders[i].get()->PlotThroughputHistogram(
931         title, bwe_names[bwe_type], kNumFlows, paused[i], optima_lines[i]);
932     metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type],
933                                                   kNumFlows, kOneWayDelayMs);
934     metric_recorders[i].get()->PlotLossHistogram(
935         title, bwe_names[bwe_type], kNumFlows,
936         receivers[i].get()->GlobalPacketLoss());
937     BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i);
938   }
939 }
940 
941 // Following functions are used for randomizing TCP file size and
942 // starting time, used on 5.7 RunMultipleShortTcpFairness.
943 // They are pseudo-random generators, creating always the same
944 // value sequence for a given Random seed.
945 
GetFileSizesBytes(int num_files)946 std::vector<int> BweTest::GetFileSizesBytes(int num_files) {
947   // File size chosen from uniform distribution between [100,1000] kB.
948   const int kMinKbytes = 100;
949   const int kMaxKbytes = 1000;
950 
951   Random random(0x12345678);
952   std::vector<int> tcp_file_sizes_bytes;
953 
954   while (num_files-- > 0) {
955     tcp_file_sizes_bytes.push_back(random.Rand(kMinKbytes, kMaxKbytes) * 1000);
956   }
957 
958   return tcp_file_sizes_bytes;
959 }
960 
GetStartingTimesMs(int num_files)961 std::vector<int64_t> BweTest::GetStartingTimesMs(int num_files) {
962   // OFF state behaves as an exp. distribution with mean = 10 seconds.
963   const float kMeanMs = 10000.0f;
964   Random random(0x12345678);
965 
966   std::vector<int64_t> tcp_starting_times_ms;
967 
968   // Two TCP Flows are initialized simultaneosly at t=0 seconds.
969   for (int i = 0; i < 2; ++i, --num_files) {
970     tcp_starting_times_ms.push_back(0);
971   }
972 
973   // Other TCP Flows are initialized in an OFF state.
974   while (num_files-- > 0) {
975     tcp_starting_times_ms.push_back(
976         static_cast<int64_t>(random.Exponential(1.0f / kMeanMs)));
977   }
978 
979   return tcp_starting_times_ms;
980 }
981 
982 }  // namespace bwe
983 }  // namespace testing
984 }  // namespace webrtc
985