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_framework.h"
     12 
     13 #include <stdio.h>
     14 
     15 #include <sstream>
     16 
     17 namespace webrtc {
     18 namespace testing {
     19 namespace bwe {
     20 
     21 class DelayCapHelper {
     22  public:
     23   // Max delay = 0 stands for +infinite.
     24   DelayCapHelper() : max_delay_us_(0), delay_stats_() {}
     25 
     26   void set_max_delay_ms(int64_t max_delay_ms) {
     27     BWE_TEST_LOGGING_ENABLE(false);
     28     BWE_TEST_LOGGING_LOG1("Max Delay", "%d ms", static_cast<int>(max_delay_ms));
     29     assert(max_delay_ms >= 0);
     30     max_delay_us_ = max_delay_ms * 1000;
     31   }
     32 
     33   bool ShouldSendPacket(int64_t send_time_us, int64_t arrival_time_us) {
     34     int64_t packet_delay_us = send_time_us - arrival_time_us;
     35     delay_stats_.Push((std::min(packet_delay_us, max_delay_us_) + 500) / 1000);
     36     return (max_delay_us_ == 0 || max_delay_us_ >= packet_delay_us);
     37   }
     38 
     39   const Stats<double>& delay_stats() const {
     40     return delay_stats_;
     41   }
     42 
     43  private:
     44   int64_t max_delay_us_;
     45   Stats<double> delay_stats_;
     46 
     47   RTC_DISALLOW_COPY_AND_ASSIGN(DelayCapHelper);
     48 };
     49 
     50 const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids) {
     51   FlowIds flow_ids(&flow_ids_array[0], flow_ids_array + num_flow_ids);
     52   return flow_ids;
     53 }
     54 
     55 const FlowIds CreateFlowIdRange(int initial_value, int last_value) {
     56   int size = last_value - initial_value + 1;
     57   assert(size > 0);
     58   int* flow_ids_array = new int[size];
     59   for (int i = initial_value; i <= last_value; ++i) {
     60     flow_ids_array[i - initial_value] = i;
     61   }
     62   return CreateFlowIds(flow_ids_array, size);
     63 }
     64 
     65 void RateCounter::UpdateRates(int64_t send_time_us, uint32_t payload_size) {
     66   ++recently_received_packets_;
     67   recently_received_bytes_ += payload_size;
     68   last_accumulated_us_ = send_time_us;
     69   window_.push_back(std::make_pair(send_time_us, payload_size));
     70   while (!window_.empty()) {
     71     const TimeSizePair& packet = window_.front();
     72     if (packet.first > (last_accumulated_us_ - window_size_us_)) {
     73       break;
     74     }
     75     assert(recently_received_packets_ >= 1);
     76     assert(recently_received_bytes_ >= packet.second);
     77     --recently_received_packets_;
     78     recently_received_bytes_ -= packet.second;
     79     window_.pop_front();
     80   }
     81 }
     82 
     83 uint32_t RateCounter::bits_per_second() const {
     84   return (8 * recently_received_bytes_) / BitrateWindowS();
     85 }
     86 
     87 uint32_t RateCounter::packets_per_second() const {
     88   return recently_received_packets_ / BitrateWindowS();
     89 }
     90 
     91 double RateCounter::BitrateWindowS() const {
     92   return static_cast<double>(window_size_us_) / (1000 * 1000);
     93 }
     94 
     95 Packet::Packet()
     96     : flow_id_(0),
     97       creation_time_us_(-1),
     98       send_time_us_(-1),
     99       sender_timestamp_us_(-1),
    100       payload_size_(0),
    101       paced_(false) {
    102 }
    103 
    104 Packet::Packet(int flow_id, int64_t send_time_us, size_t payload_size)
    105     : flow_id_(flow_id),
    106       creation_time_us_(send_time_us),
    107       send_time_us_(send_time_us),
    108       sender_timestamp_us_(send_time_us),
    109       payload_size_(payload_size),
    110       paced_(false) {
    111 }
    112 
    113 Packet::~Packet() {
    114 }
    115 
    116 bool Packet::operator<(const Packet& rhs) const {
    117   return send_time_us_ < rhs.send_time_us_;
    118 }
    119 
    120 void Packet::set_send_time_us(int64_t send_time_us) {
    121   assert(send_time_us >= 0);
    122   send_time_us_ = send_time_us;
    123 }
    124 
    125 MediaPacket::MediaPacket() {
    126   memset(&header_, 0, sizeof(header_));
    127 }
    128 
    129 MediaPacket::MediaPacket(int flow_id,
    130                          int64_t send_time_us,
    131                          size_t payload_size,
    132                          uint16_t sequence_number)
    133     : Packet(flow_id, send_time_us, payload_size) {
    134   header_ = RTPHeader();
    135   header_.sequenceNumber = sequence_number;
    136 }
    137 
    138 MediaPacket::MediaPacket(int flow_id,
    139                          int64_t send_time_us,
    140                          size_t payload_size,
    141                          const RTPHeader& header)
    142     : Packet(flow_id, send_time_us, payload_size), header_(header) {
    143 }
    144 
    145 MediaPacket::MediaPacket(int64_t send_time_us, uint16_t sequence_number)
    146     : Packet(0, send_time_us, 0) {
    147   header_ = RTPHeader();
    148   header_.sequenceNumber = sequence_number;
    149 }
    150 
    151 void MediaPacket::SetAbsSendTimeMs(int64_t abs_send_time_ms) {
    152   header_.extension.hasAbsoluteSendTime = true;
    153   header_.extension.absoluteSendTime = ((static_cast<int64_t>(abs_send_time_ms *
    154     (1 << 18)) + 500) / 1000) & 0x00fffffful;
    155 }
    156 
    157 RembFeedback::RembFeedback(int flow_id,
    158                            int64_t send_time_us,
    159                            int64_t last_send_time_ms,
    160                            uint32_t estimated_bps,
    161                            RTCPReportBlock report_block)
    162     : FeedbackPacket(flow_id, send_time_us, last_send_time_ms),
    163       estimated_bps_(estimated_bps),
    164       report_block_(report_block) {
    165 }
    166 
    167 SendSideBweFeedback::SendSideBweFeedback(
    168     int flow_id,
    169     int64_t send_time_us,
    170     int64_t last_send_time_ms,
    171     const std::vector<PacketInfo>& packet_feedback_vector)
    172     : FeedbackPacket(flow_id, send_time_us, last_send_time_ms),
    173       packet_feedback_vector_(packet_feedback_vector) {
    174 }
    175 
    176 bool IsTimeSorted(const Packets& packets) {
    177   PacketsConstIt last_it = packets.begin();
    178   for (PacketsConstIt it = last_it; it != packets.end(); ++it) {
    179     if (it != last_it && **it < **last_it) {
    180       return false;
    181     }
    182     last_it = it;
    183   }
    184   return true;
    185 }
    186 
    187 PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
    188                                  int flow_id,
    189                                  ProcessorType type)
    190     : listener_(listener), flow_ids_(&flow_id, &flow_id + 1) {
    191   if (listener_) {
    192     listener_->AddPacketProcessor(this, type);
    193   }
    194 }
    195 
    196 PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
    197                                  const FlowIds& flow_ids,
    198                                  ProcessorType type)
    199     : listener_(listener), flow_ids_(flow_ids) {
    200   if (listener_) {
    201     listener_->AddPacketProcessor(this, type);
    202   }
    203 }
    204 
    205 PacketProcessor::~PacketProcessor() {
    206   if (listener_) {
    207     listener_->RemovePacketProcessor(this);
    208   }
    209 }
    210 
    211 uint32_t PacketProcessor::packets_per_second() const {
    212   return rate_counter_.packets_per_second();
    213 }
    214 
    215 uint32_t PacketProcessor::bits_per_second() const {
    216   return rate_counter_.bits_per_second();
    217 }
    218 
    219 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
    220                                      int flow_id,
    221                                      const char* name,
    222                                      const std::string& plot_name)
    223     : PacketProcessor(listener, flow_id, kRegular),
    224       packets_per_second_stats_(),
    225       kbps_stats_(),
    226       start_plotting_time_ms_(0),
    227       plot_name_(plot_name) {
    228   std::stringstream ss;
    229   ss << name << "_" << flow_id;
    230   name_ = ss.str();
    231 }
    232 
    233 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
    234                                      const FlowIds& flow_ids,
    235                                      const char* name,
    236                                      const std::string& plot_name)
    237     : PacketProcessor(listener, flow_ids, kRegular),
    238       packets_per_second_stats_(),
    239       kbps_stats_(),
    240       start_plotting_time_ms_(0),
    241       plot_name_(plot_name) {
    242   std::stringstream ss;
    243   ss << name;
    244   char delimiter = '_';
    245   for (int flow_id : flow_ids) {
    246     ss << delimiter << flow_id;
    247     delimiter = ',';
    248   }
    249   name_ = ss.str();
    250 }
    251 
    252 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
    253                                      const FlowIds& flow_ids,
    254                                      const char* name,
    255                                      int64_t start_plotting_time_ms,
    256                                      const std::string& plot_name)
    257     : RateCounterFilter(listener, flow_ids, name, plot_name) {
    258   start_plotting_time_ms_ = start_plotting_time_ms;
    259 }
    260 
    261 RateCounterFilter::~RateCounterFilter() {
    262   LogStats();
    263 }
    264 
    265 
    266 void RateCounterFilter::LogStats() {
    267   BWE_TEST_LOGGING_CONTEXT("RateCounterFilter");
    268   packets_per_second_stats_.Log("pps");
    269   kbps_stats_.Log("kbps");
    270 }
    271 
    272 Stats<double> RateCounterFilter::GetBitrateStats() const {
    273   return kbps_stats_;
    274 }
    275 
    276 void RateCounterFilter::Plot(int64_t timestamp_ms) {
    277   uint32_t plot_kbps = 0;
    278   if (timestamp_ms >= start_plotting_time_ms_) {
    279     plot_kbps = rate_counter_.bits_per_second() / 1000.0;
    280   }
    281   BWE_TEST_LOGGING_CONTEXT(name_.c_str());
    282   if (plot_name_.empty()) {
    283     BWE_TEST_LOGGING_PLOT(0, "Throughput_kbps#1", timestamp_ms, plot_kbps);
    284   } else {
    285     BWE_TEST_LOGGING_PLOT_WITH_NAME(0, "Throughput_kbps#1", timestamp_ms,
    286                                     plot_kbps, plot_name_);
    287   }
    288 
    289   RTC_UNUSED(plot_kbps);
    290 }
    291 
    292 void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
    293   assert(in_out);
    294   for (const Packet* packet : *in_out) {
    295     rate_counter_.UpdateRates(packet->send_time_us(),
    296                               static_cast<int>(packet->payload_size()));
    297   }
    298   packets_per_second_stats_.Push(rate_counter_.packets_per_second());
    299   kbps_stats_.Push(rate_counter_.bits_per_second() / 1000.0);
    300 }
    301 
    302 LossFilter::LossFilter(PacketProcessorListener* listener, int flow_id)
    303     : PacketProcessor(listener, flow_id, kRegular),
    304       random_(0x12345678),
    305       loss_fraction_(0.0f) {
    306 }
    307 
    308 LossFilter::LossFilter(PacketProcessorListener* listener,
    309                        const FlowIds& flow_ids)
    310     : PacketProcessor(listener, flow_ids, kRegular),
    311       random_(0x12345678),
    312       loss_fraction_(0.0f) {
    313 }
    314 
    315 void LossFilter::SetLoss(float loss_percent) {
    316   BWE_TEST_LOGGING_ENABLE(false);
    317   BWE_TEST_LOGGING_LOG1("Loss", "%f%%", loss_percent);
    318   assert(loss_percent >= 0.0f);
    319   assert(loss_percent <= 100.0f);
    320   loss_fraction_ = loss_percent * 0.01f;
    321 }
    322 
    323 void LossFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
    324   assert(in_out);
    325   for (PacketsIt it = in_out->begin(); it != in_out->end(); ) {
    326     if (random_.Rand<float>() < loss_fraction_) {
    327       delete *it;
    328       it = in_out->erase(it);
    329     } else {
    330       ++it;
    331     }
    332   }
    333 }
    334 
    335 const int64_t kDefaultOneWayDelayUs = 0;
    336 
    337 DelayFilter::DelayFilter(PacketProcessorListener* listener, int flow_id)
    338     : PacketProcessor(listener, flow_id, kRegular),
    339       one_way_delay_us_(kDefaultOneWayDelayUs),
    340       last_send_time_us_(0) {
    341 }
    342 
    343 DelayFilter::DelayFilter(PacketProcessorListener* listener,
    344                          const FlowIds& flow_ids)
    345     : PacketProcessor(listener, flow_ids, kRegular),
    346       one_way_delay_us_(kDefaultOneWayDelayUs),
    347       last_send_time_us_(0) {
    348 }
    349 
    350 void DelayFilter::SetOneWayDelayMs(int64_t one_way_delay_ms) {
    351   BWE_TEST_LOGGING_ENABLE(false);
    352   BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast<int>(one_way_delay_ms));
    353   assert(one_way_delay_ms >= 0);
    354   one_way_delay_us_ = one_way_delay_ms * 1000;
    355 }
    356 
    357 void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
    358   assert(in_out);
    359   for (Packet* packet : *in_out) {
    360     int64_t new_send_time_us = packet->send_time_us() + one_way_delay_us_;
    361     last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
    362     packet->set_send_time_us(last_send_time_us_);
    363   }
    364 }
    365 
    366 JitterFilter::JitterFilter(PacketProcessorListener* listener, int flow_id)
    367     : PacketProcessor(listener, flow_id, kRegular),
    368       random_(0x89674523),
    369       stddev_jitter_us_(0),
    370       last_send_time_us_(0),
    371       reordering_(false) {
    372 }
    373 
    374 JitterFilter::JitterFilter(PacketProcessorListener* listener,
    375                            const FlowIds& flow_ids)
    376     : PacketProcessor(listener, flow_ids, kRegular),
    377       random_(0x89674523),
    378       stddev_jitter_us_(0),
    379       last_send_time_us_(0),
    380       reordering_(false) {
    381 }
    382 
    383 const int kN = 3;  // Truncated N sigma gaussian.
    384 
    385 void JitterFilter::SetMaxJitter(int64_t max_jitter_ms) {
    386   BWE_TEST_LOGGING_ENABLE(false);
    387   BWE_TEST_LOGGING_LOG1("Max Jitter", "%d ms", static_cast<int>(max_jitter_ms));
    388   assert(max_jitter_ms >= 0);
    389   // Truncated gaussian, Max jitter = kN*sigma.
    390   stddev_jitter_us_ = (max_jitter_ms * 1000 + kN / 2) / kN;
    391 }
    392 
    393 namespace {
    394 inline int64_t TruncatedNSigmaGaussian(Random* const random,
    395                                        int64_t mean,
    396                                        int64_t std_dev) {
    397   int64_t gaussian_random = random->Gaussian(mean, std_dev);
    398   return std::max(std::min(gaussian_random, kN * std_dev), -kN * std_dev);
    399 }
    400 }
    401 
    402 void JitterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
    403   assert(in_out);
    404   for (Packet* packet : *in_out) {
    405     int64_t jitter_us =
    406         std::abs(TruncatedNSigmaGaussian(&random_, 0, stddev_jitter_us_));
    407     int64_t new_send_time_us = packet->send_time_us() + jitter_us;
    408 
    409     if (!reordering_) {
    410       new_send_time_us = std::max(last_send_time_us_, new_send_time_us);
    411     }
    412 
    413     // Receiver timestamp cannot be lower than sender timestamp.
    414     assert(new_send_time_us >= packet->sender_timestamp_us());
    415 
    416     packet->set_send_time_us(new_send_time_us);
    417     last_send_time_us_ = new_send_time_us;
    418   }
    419 }
    420 
    421 // Computes the expected value for a right sided (abs) truncated gaussian.
    422 // Does not take into account  possible reoerdering updates.
    423 int64_t JitterFilter::MeanUs() {
    424   const double kPi = 3.1415926535897932;
    425   double max_jitter_us = static_cast<double>(kN * stddev_jitter_us_);
    426   double right_sided_mean_us =
    427       static_cast<double>(stddev_jitter_us_) / sqrt(kPi / 2.0);
    428   double truncated_mean_us =
    429       right_sided_mean_us *
    430           (1.0 - exp(-pow(static_cast<double>(kN), 2.0) / 2.0)) +
    431       max_jitter_us * erfc(static_cast<double>(kN));
    432   return static_cast<int64_t>(truncated_mean_us + 0.5);
    433 }
    434 
    435 ReorderFilter::ReorderFilter(PacketProcessorListener* listener, int flow_id)
    436     : PacketProcessor(listener, flow_id, kRegular),
    437       random_(0x27452389),
    438       reorder_fraction_(0.0f) {
    439 }
    440 
    441 ReorderFilter::ReorderFilter(PacketProcessorListener* listener,
    442                              const FlowIds& flow_ids)
    443     : PacketProcessor(listener, flow_ids, kRegular),
    444       random_(0x27452389),
    445       reorder_fraction_(0.0f) {
    446 }
    447 
    448 void ReorderFilter::SetReorder(float reorder_percent) {
    449   BWE_TEST_LOGGING_ENABLE(false);
    450   BWE_TEST_LOGGING_LOG1("Reordering", "%f%%", reorder_percent);
    451   assert(reorder_percent >= 0.0f);
    452   assert(reorder_percent <= 100.0f);
    453   reorder_fraction_ = reorder_percent * 0.01f;
    454 }
    455 
    456 void ReorderFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
    457   assert(in_out);
    458   if (in_out->size() >= 2) {
    459     PacketsIt last_it = in_out->begin();
    460     PacketsIt it = last_it;
    461     while (++it != in_out->end()) {
    462       if (random_.Rand<float>() < reorder_fraction_) {
    463         int64_t t1 = (*last_it)->send_time_us();
    464         int64_t t2 = (*it)->send_time_us();
    465         std::swap(*last_it, *it);
    466         (*last_it)->set_send_time_us(t1);
    467         (*it)->set_send_time_us(t2);
    468       }
    469       last_it = it;
    470     }
    471   }
    472 }
    473 
    474 const uint32_t kDefaultKbps = 1200;
    475 
    476 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, int flow_id)
    477     : PacketProcessor(listener, flow_id, kRegular),
    478       capacity_kbps_(kDefaultKbps),
    479       last_send_time_us_(0),
    480       delay_cap_helper_(new DelayCapHelper()) {
    481 }
    482 
    483 ChokeFilter::ChokeFilter(PacketProcessorListener* listener,
    484                          const FlowIds& flow_ids)
    485     : PacketProcessor(listener, flow_ids, kRegular),
    486       capacity_kbps_(kDefaultKbps),
    487       last_send_time_us_(0),
    488       delay_cap_helper_(new DelayCapHelper()) {
    489 }
    490 
    491 ChokeFilter::~ChokeFilter() {}
    492 
    493 void ChokeFilter::set_capacity_kbps(uint32_t kbps) {
    494   BWE_TEST_LOGGING_ENABLE(false);
    495   BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps);
    496   capacity_kbps_ = kbps;
    497 }
    498 
    499 uint32_t ChokeFilter::capacity_kbps() {
    500   return capacity_kbps_;
    501 }
    502 
    503 void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
    504   assert(in_out);
    505   for (PacketsIt it = in_out->begin(); it != in_out->end(); ) {
    506     int64_t earliest_send_time_us =
    507         std::max(last_send_time_us_, (*it)->send_time_us());
    508 
    509     int64_t new_send_time_us =
    510         earliest_send_time_us +
    511         ((*it)->payload_size() * 8 * 1000 + capacity_kbps_ / 2) /
    512             capacity_kbps_;
    513 
    514     if (delay_cap_helper_->ShouldSendPacket(new_send_time_us,
    515                                             (*it)->send_time_us())) {
    516       (*it)->set_send_time_us(new_send_time_us);
    517       last_send_time_us_ = new_send_time_us;
    518       ++it;
    519     } else {
    520       delete *it;
    521       it = in_out->erase(it);
    522     }
    523   }
    524 }
    525 
    526 void ChokeFilter::set_max_delay_ms(int64_t max_delay_ms) {
    527   delay_cap_helper_->set_max_delay_ms(max_delay_ms);
    528 }
    529 
    530 Stats<double> ChokeFilter::GetDelayStats() const {
    531   return delay_cap_helper_->delay_stats();
    532 }
    533 
    534 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
    535     PacketProcessorListener* listener,
    536     int flow_id)
    537     : PacketProcessor(listener, flow_id, kRegular),
    538       current_offset_us_(0),
    539       delivery_times_us_(),
    540       next_delivery_it_(),
    541       local_time_us_(-1),
    542       rate_counter_(new RateCounter),
    543       name_(""),
    544       delay_cap_helper_(new DelayCapHelper()),
    545       packets_per_second_stats_(),
    546       kbps_stats_() {
    547 }
    548 
    549 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
    550     PacketProcessorListener* listener,
    551     const FlowIds& flow_ids)
    552     : PacketProcessor(listener, flow_ids, kRegular),
    553       current_offset_us_(0),
    554       delivery_times_us_(),
    555       next_delivery_it_(),
    556       local_time_us_(-1),
    557       rate_counter_(new RateCounter),
    558       name_(""),
    559       delay_cap_helper_(new DelayCapHelper()),
    560       packets_per_second_stats_(),
    561       kbps_stats_() {
    562 }
    563 
    564 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
    565     PacketProcessorListener* listener,
    566     int flow_id,
    567     const char* name)
    568     : PacketProcessor(listener, flow_id, kRegular),
    569       current_offset_us_(0),
    570       delivery_times_us_(),
    571       next_delivery_it_(),
    572       local_time_us_(-1),
    573       rate_counter_(new RateCounter),
    574       name_(name),
    575       delay_cap_helper_(new DelayCapHelper()),
    576       packets_per_second_stats_(),
    577       kbps_stats_() {
    578 }
    579 
    580 TraceBasedDeliveryFilter::~TraceBasedDeliveryFilter() {
    581 }
    582 
    583 bool TraceBasedDeliveryFilter::Init(const std::string& filename) {
    584   FILE* trace_file = fopen(filename.c_str(), "r");
    585   if (!trace_file) {
    586     return false;
    587   }
    588   int64_t first_timestamp = -1;
    589   while (!feof(trace_file)) {
    590     const size_t kMaxLineLength = 100;
    591     char line[kMaxLineLength];
    592     if (fgets(line, kMaxLineLength, trace_file)) {
    593       std::string line_string(line);
    594       std::istringstream buffer(line_string);
    595       int64_t timestamp;
    596       buffer >> timestamp;
    597       timestamp /= 1000;  // Convert to microseconds.
    598       if (first_timestamp == -1)
    599         first_timestamp = timestamp;
    600       assert(delivery_times_us_.empty() ||
    601              timestamp - first_timestamp - delivery_times_us_.back() >= 0);
    602       delivery_times_us_.push_back(timestamp - first_timestamp);
    603     }
    604   }
    605   assert(!delivery_times_us_.empty());
    606   next_delivery_it_ = delivery_times_us_.begin();
    607   fclose(trace_file);
    608   return true;
    609 }
    610 
    611 void TraceBasedDeliveryFilter::Plot(int64_t timestamp_ms) {
    612   BWE_TEST_LOGGING_CONTEXT(name_.c_str());
    613   // This plots the max possible throughput of the trace-based delivery filter,
    614   // which will be reached if a packet sent on every packet slot of the trace.
    615   BWE_TEST_LOGGING_PLOT(0, "MaxThroughput_#1", timestamp_ms,
    616                         rate_counter_->bits_per_second() / 1000.0);
    617 }
    618 
    619 void TraceBasedDeliveryFilter::RunFor(int64_t time_ms, Packets* in_out) {
    620   assert(in_out);
    621   for (PacketsIt it = in_out->begin(); it != in_out->end();) {
    622     while (local_time_us_ < (*it)->send_time_us()) {
    623       ProceedToNextSlot();
    624     }
    625     // Drop any packets that have been queued for too long.
    626     while (!delay_cap_helper_->ShouldSendPacket(local_time_us_,
    627                                                 (*it)->send_time_us())) {
    628       delete *it;
    629       it = in_out->erase(it);
    630       if (it == in_out->end()) {
    631         return;
    632       }
    633     }
    634     if (local_time_us_ >= (*it)->send_time_us()) {
    635       (*it)->set_send_time_us(local_time_us_);
    636       ProceedToNextSlot();
    637     }
    638     ++it;
    639   }
    640   packets_per_second_stats_.Push(rate_counter_->packets_per_second());
    641   kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0);
    642 }
    643 
    644 void TraceBasedDeliveryFilter::set_max_delay_ms(int64_t max_delay_ms) {
    645   delay_cap_helper_->set_max_delay_ms(max_delay_ms);
    646 }
    647 
    648 Stats<double> TraceBasedDeliveryFilter::GetDelayStats() const {
    649   return delay_cap_helper_->delay_stats();
    650 }
    651 
    652 Stats<double> TraceBasedDeliveryFilter::GetBitrateStats() const {
    653   return kbps_stats_;
    654 }
    655 
    656 void TraceBasedDeliveryFilter::ProceedToNextSlot() {
    657   if (*next_delivery_it_ <= local_time_us_) {
    658     ++next_delivery_it_;
    659     if (next_delivery_it_ == delivery_times_us_.end()) {
    660       // When the trace wraps we allow two packets to be sent back-to-back.
    661       for (int64_t& delivery_time_us : delivery_times_us_) {
    662         delivery_time_us += local_time_us_ - current_offset_us_;
    663       }
    664       current_offset_us_ += local_time_us_ - current_offset_us_;
    665       next_delivery_it_ = delivery_times_us_.begin();
    666     }
    667   }
    668   local_time_us_ = *next_delivery_it_;
    669   const int kPayloadSize = 1200;
    670   rate_counter_->UpdateRates(local_time_us_, kPayloadSize);
    671 }
    672 
    673 VideoSource::VideoSource(int flow_id,
    674                          float fps,
    675                          uint32_t kbps,
    676                          uint32_t ssrc,
    677                          int64_t first_frame_offset_ms)
    678     : kMaxPayloadSizeBytes(1200),
    679       kTimestampBase(0xff80ff00ul),
    680       frame_period_ms_(1000.0 / fps),
    681       bits_per_second_(1000 * kbps),
    682       frame_size_bytes_(bits_per_second_ / 8 / fps),
    683       random_(0x12345678),
    684       flow_id_(flow_id),
    685       next_frame_ms_(first_frame_offset_ms),
    686       next_frame_rand_ms_(0),
    687       now_ms_(0),
    688       prototype_header_() {
    689   memset(&prototype_header_, 0, sizeof(prototype_header_));
    690   prototype_header_.ssrc = ssrc;
    691   prototype_header_.sequenceNumber = 0xf000u;
    692 }
    693 
    694 uint32_t VideoSource::NextFrameSize() {
    695   return frame_size_bytes_;
    696 }
    697 
    698 int64_t VideoSource::GetTimeUntilNextFrameMs() const {
    699   return next_frame_ms_ + next_frame_rand_ms_ - now_ms_;
    700 }
    701 
    702 uint32_t VideoSource::NextPacketSize(uint32_t frame_size,
    703                                      uint32_t remaining_payload) {
    704   return std::min(kMaxPayloadSizeBytes, remaining_payload);
    705 }
    706 
    707 void VideoSource::RunFor(int64_t time_ms, Packets* in_out) {
    708   assert(in_out);
    709 
    710   now_ms_ += time_ms;
    711   Packets new_packets;
    712 
    713   while (now_ms_ >= next_frame_ms_) {
    714     const int64_t kRandAmplitude = 2;
    715     // A variance picked uniformly from {-1, 0, 1} ms is added to the frame
    716     // timestamp.
    717     next_frame_rand_ms_ = kRandAmplitude * (random_.Rand<float>() - 0.5);
    718 
    719     // Ensure frame will not have a negative timestamp.
    720     int64_t next_frame_ms =
    721         std::max<int64_t>(next_frame_ms_ + next_frame_rand_ms_, 0);
    722 
    723     prototype_header_.timestamp =
    724         kTimestampBase + static_cast<uint32_t>(next_frame_ms * 90.0);
    725     prototype_header_.extension.transmissionTimeOffset = 0;
    726 
    727     // Generate new packets for this frame, all with the same timestamp,
    728     // but the payload size is capped, so if the whole frame doesn't fit in
    729     // one packet, we will see a number of equally sized packets followed by
    730     // one smaller at the tail.
    731 
    732     int64_t send_time_us = next_frame_ms * 1000.0;
    733 
    734     uint32_t frame_size = NextFrameSize();
    735     uint32_t payload_size = frame_size;
    736 
    737     while (payload_size > 0) {
    738       ++prototype_header_.sequenceNumber;
    739       uint32_t size = NextPacketSize(frame_size, payload_size);
    740       MediaPacket* new_packet =
    741           new MediaPacket(flow_id_, send_time_us, size, prototype_header_);
    742       new_packets.push_back(new_packet);
    743       new_packet->SetAbsSendTimeMs(next_frame_ms);
    744       new_packet->set_sender_timestamp_us(send_time_us);
    745       payload_size -= size;
    746     }
    747 
    748     next_frame_ms_ += frame_period_ms_;
    749   }
    750 
    751   in_out->merge(new_packets, DereferencingComparator<Packet>);
    752 }
    753 
    754 AdaptiveVideoSource::AdaptiveVideoSource(int flow_id,
    755                                          float fps,
    756                                          uint32_t kbps,
    757                                          uint32_t ssrc,
    758                                          int64_t first_frame_offset_ms)
    759     : VideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms) {
    760 }
    761 
    762 void AdaptiveVideoSource::SetBitrateBps(int bitrate_bps) {
    763   bits_per_second_ = std::min(bitrate_bps, 2500000);
    764   frame_size_bytes_ = (bits_per_second_ / 8 * frame_period_ms_ + 500) / 1000;
    765 }
    766 
    767 PeriodicKeyFrameSource::PeriodicKeyFrameSource(int flow_id,
    768                                                float fps,
    769                                                uint32_t kbps,
    770                                                uint32_t ssrc,
    771                                                int64_t first_frame_offset_ms,
    772                                                int key_frame_interval)
    773     : AdaptiveVideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms),
    774       key_frame_interval_(key_frame_interval),
    775       frame_counter_(0),
    776       compensation_bytes_(0),
    777       compensation_per_frame_(0) {
    778 }
    779 
    780 uint32_t PeriodicKeyFrameSource::NextFrameSize() {
    781   uint32_t payload_size = frame_size_bytes_;
    782   if (frame_counter_ == 0) {
    783     payload_size = kMaxPayloadSizeBytes * 12;
    784     compensation_bytes_ = 4 * frame_size_bytes_;
    785     compensation_per_frame_ = compensation_bytes_ / 30;
    786   } else if (key_frame_interval_ > 0 &&
    787              (frame_counter_ % key_frame_interval_ == 0)) {
    788     payload_size *= 5;
    789     compensation_bytes_ = payload_size - frame_size_bytes_;
    790     compensation_per_frame_ = compensation_bytes_ / 30;
    791   } else if (compensation_bytes_ > 0) {
    792     if (compensation_per_frame_ > static_cast<int>(payload_size)) {
    793       // Skip this frame.
    794       compensation_bytes_ -= payload_size;
    795       payload_size = 0;
    796     } else {
    797       payload_size -= compensation_per_frame_;
    798       compensation_bytes_ -= compensation_per_frame_;
    799     }
    800   }
    801   if (compensation_bytes_ < 0)
    802     compensation_bytes_ = 0;
    803   ++frame_counter_;
    804   return payload_size;
    805 }
    806 
    807 uint32_t PeriodicKeyFrameSource::NextPacketSize(uint32_t frame_size,
    808                                                 uint32_t remaining_payload) {
    809   uint32_t fragments =
    810       (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes;
    811   uint32_t avg_size = (frame_size + fragments - 1) / fragments;
    812   return std::min(avg_size, remaining_payload);
    813 }
    814 }  // namespace bwe
    815 }  // namespace testing
    816 }  // namespace webrtc
    817