Home | History | Annotate | Download | only in test
      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 
     33 PacketProcessorRunner::PacketProcessorRunner(PacketProcessor* processor)
     34     : processor_(processor) {
     35 }
     36 
     37 PacketProcessorRunner::~PacketProcessorRunner() {
     38   for (Packet* packet : queue_)
     39     delete packet;
     40 }
     41 
     42 bool PacketProcessorRunner::RunsProcessor(
     43     const PacketProcessor* processor) const {
     44   return processor == processor_;
     45 }
     46 
     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 
     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 
     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.
     97 BweTest::BweTest() : BweTest(true) {
     98 }
     99 
    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 
    109 BweTest::~BweTest() {
    110   for (Packet* packet : packets_)
    111     delete packet;
    112 }
    113 
    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 
    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 
    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.
    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 
    157 void BweTest::VerboseLogging(bool enable) {
    158   BWE_TEST_LOGGING_GLOBAL_ENABLE(enable);
    159 }
    160 
    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 
    185 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 
    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 
    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 
    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 
    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 
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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 
    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 
    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