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 #ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FRAMEWORK_H_
     12 #define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FRAMEWORK_H_
     13 
     14 #include <assert.h>
     15 #include <math.h>
     16 
     17 #include <algorithm>
     18 #include <list>
     19 #include <numeric>
     20 #include <sstream>
     21 #include <string>
     22 #include <vector>
     23 
     24 #include "webrtc/modules/interface/module_common_types.h"
     25 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
     26 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     27 
     28 namespace webrtc {
     29 namespace testing {
     30 namespace bwe {
     31 
     32 class DelayCapHelper;
     33 class RateCounter;
     34 
     35 
     36 typedef std::vector<int> FlowIds;
     37 const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids);
     38 
     39 template<typename T> class Stats {
     40  public:
     41   Stats()
     42       : data_(),
     43         last_mean_count_(0),
     44         last_variance_count_(0),
     45         last_minmax_count_(0),
     46         mean_(0),
     47         variance_(0),
     48         min_(0),
     49         max_(0) {
     50   }
     51 
     52   void Push(T data_point) {
     53     data_.push_back(data_point);
     54   }
     55 
     56   T GetMean() {
     57     if (last_mean_count_ != data_.size()) {
     58       last_mean_count_ = data_.size();
     59       mean_ = std::accumulate(data_.begin(), data_.end(), static_cast<T>(0));
     60       assert(last_mean_count_ != 0);
     61       mean_ /= static_cast<T>(last_mean_count_);
     62     }
     63     return mean_;
     64   }
     65   T GetVariance() {
     66     if (last_variance_count_ != data_.size()) {
     67       last_variance_count_ = data_.size();
     68       T mean = GetMean();
     69       variance_ = 0;
     70       for (typename std::vector<T>::const_iterator it = data_.begin();
     71           it != data_.end(); ++it) {
     72         T diff = (*it - mean);
     73         variance_ += diff * diff;
     74       }
     75       assert(last_variance_count_ != 0);
     76       variance_ /= static_cast<T>(last_variance_count_);
     77     }
     78     return variance_;
     79   }
     80   T GetStdDev() {
     81     return sqrt(static_cast<double>(GetVariance()));
     82   }
     83   T GetMin() {
     84     RefreshMinMax();
     85     return min_;
     86   }
     87   T GetMax() {
     88     RefreshMinMax();
     89     return max_;
     90   }
     91 
     92   std::string AsString() {
     93     std::stringstream ss;
     94     ss << (GetMean() >= 0 ? GetMean() : -1) << ", " <<
     95         (GetStdDev() >= 0 ? GetStdDev() : -1);
     96     return ss.str();
     97   }
     98 
     99   void Log(const std::string& units) {
    100     BWE_TEST_LOGGING_LOG5("", "%f %s\t+/-%f\t[%f,%f]",
    101         GetMean(), units.c_str(), GetStdDev(), GetMin(), GetMax());
    102   }
    103 
    104  private:
    105   void RefreshMinMax() {
    106     if (last_minmax_count_ != data_.size()) {
    107       last_minmax_count_ = data_.size();
    108       min_ = max_ = 0;
    109       if (data_.empty()) {
    110         return;
    111       }
    112       typename std::vector<T>::const_iterator it = data_.begin();
    113       min_ = max_ = *it;
    114       while (++it != data_.end()) {
    115         min_ = std::min(min_, *it);
    116         max_ = std::max(max_, *it);
    117       }
    118     }
    119   }
    120 
    121   std::vector<T> data_;
    122   typename std::vector<T>::size_type last_mean_count_;
    123   typename std::vector<T>::size_type last_variance_count_;
    124   typename std::vector<T>::size_type last_minmax_count_;
    125   T mean_;
    126   T variance_;
    127   T min_;
    128   T max_;
    129 };
    130 
    131 class Random {
    132  public:
    133   explicit Random(uint32_t seed);
    134 
    135   // Return pseudo random number in the interval [0.0, 1.0].
    136   float Rand();
    137 
    138   // Normal Distribution.
    139   int Gaussian(int mean, int standard_deviation);
    140 
    141   // TODO(solenberg): Random from histogram.
    142   // template<typename T> int Distribution(const std::vector<T> histogram) {
    143 
    144  private:
    145   uint32_t a_;
    146   uint32_t b_;
    147 
    148   DISALLOW_IMPLICIT_CONSTRUCTORS(Random);
    149 };
    150 
    151 class Packet {
    152  public:
    153   Packet();
    154   Packet(int flow_id, int64_t send_time_us, uint32_t payload_size,
    155          const RTPHeader& header);
    156   Packet(int64_t send_time_us, uint32_t sequence_number);
    157 
    158   bool operator<(const Packet& rhs) const;
    159 
    160   int flow_id() const { return flow_id_; }
    161   int64_t creation_time_us() const { return creation_time_us_; }
    162   void set_send_time_us(int64_t send_time_us);
    163   int64_t send_time_us() const { return send_time_us_; }
    164   uint32_t payload_size() const { return payload_size_; }
    165   const RTPHeader& header() const { return header_; }
    166 
    167  private:
    168   int flow_id_;
    169   int64_t creation_time_us_;  // Time when the packet was created.
    170   int64_t send_time_us_;   // Time the packet left last processor touching it.
    171   uint32_t payload_size_;  // Size of the (non-existent, simulated) payload.
    172   RTPHeader header_;       // Actual contents.
    173 };
    174 
    175 typedef std::list<Packet> Packets;
    176 typedef std::list<Packet>::iterator PacketsIt;
    177 typedef std::list<Packet>::const_iterator PacketsConstIt;
    178 
    179 bool IsTimeSorted(const Packets& packets);
    180 
    181 class PacketProcessor;
    182 
    183 class PacketProcessorListener {
    184  public:
    185   virtual ~PacketProcessorListener() {}
    186 
    187   virtual void AddPacketProcessor(PacketProcessor* processor,
    188                                   bool is_sender) = 0;
    189   virtual void RemovePacketProcessor(PacketProcessor* processor) = 0;
    190 };
    191 
    192 class PacketProcessor {
    193  public:
    194   PacketProcessor(PacketProcessorListener* listener, bool is_sender);
    195   PacketProcessor(PacketProcessorListener* listener, const FlowIds& flow_ids,
    196                   bool is_sender);
    197   virtual ~PacketProcessor();
    198 
    199   // Called after each simulation batch to allow the processor to plot any
    200   // internal data.
    201   virtual void Plot(int64_t timestamp_ms) {}
    202 
    203   // Run simulation for |time_ms| micro seconds, consuming packets from, and
    204   // producing packets into in_out. The outgoing packet list must be sorted on
    205   // |send_time_us_|. The simulation time |time_ms| is optional to use.
    206   virtual void RunFor(int64_t time_ms, Packets* in_out) = 0;
    207 
    208   const FlowIds& flow_ids() const { return flow_ids_; }
    209 
    210  private:
    211   PacketProcessorListener* listener_;
    212   FlowIds flow_ids_;
    213 
    214   DISALLOW_COPY_AND_ASSIGN(PacketProcessor);
    215 };
    216 
    217 class RateCounterFilter : public PacketProcessor {
    218  public:
    219   explicit RateCounterFilter(PacketProcessorListener* listener);
    220   RateCounterFilter(PacketProcessorListener* listener,
    221                     const std::string& name);
    222   RateCounterFilter(PacketProcessorListener* listener,
    223                     const FlowIds& flow_ids,
    224                     const std::string& name);
    225   virtual ~RateCounterFilter();
    226 
    227   uint32_t packets_per_second() const;
    228   uint32_t bits_per_second() const;
    229 
    230   void LogStats();
    231   Stats<double> GetBitrateStats() const;
    232   virtual void Plot(int64_t timestamp_ms);
    233   virtual void RunFor(int64_t time_ms, Packets* in_out);
    234 
    235  private:
    236   scoped_ptr<RateCounter> rate_counter_;
    237   Stats<double> packets_per_second_stats_;
    238   Stats<double> kbps_stats_;
    239   std::string name_;
    240 
    241   DISALLOW_IMPLICIT_CONSTRUCTORS(RateCounterFilter);
    242 };
    243 
    244 class LossFilter : public PacketProcessor {
    245  public:
    246   explicit LossFilter(PacketProcessorListener* listener);
    247   virtual ~LossFilter() {}
    248 
    249   void SetLoss(float loss_percent);
    250   virtual void RunFor(int64_t time_ms, Packets* in_out);
    251 
    252  private:
    253   Random random_;
    254   float loss_fraction_;
    255 
    256   DISALLOW_IMPLICIT_CONSTRUCTORS(LossFilter);
    257 };
    258 
    259 class DelayFilter : public PacketProcessor {
    260  public:
    261   explicit DelayFilter(PacketProcessorListener* listener);
    262   virtual ~DelayFilter() {}
    263 
    264   void SetDelay(int64_t delay_ms);
    265   virtual void RunFor(int64_t time_ms, Packets* in_out);
    266 
    267  private:
    268   int64_t delay_us_;
    269   int64_t last_send_time_us_;
    270 
    271   DISALLOW_IMPLICIT_CONSTRUCTORS(DelayFilter);
    272 };
    273 
    274 class JitterFilter : public PacketProcessor {
    275  public:
    276   explicit JitterFilter(PacketProcessorListener* listener);
    277   virtual ~JitterFilter() {}
    278 
    279   void SetJitter(int64_t stddev_jitter_ms);
    280   virtual void RunFor(int64_t time_ms, Packets* in_out);
    281 
    282  private:
    283   Random random_;
    284   int64_t stddev_jitter_us_;
    285   int64_t last_send_time_us_;
    286 
    287   DISALLOW_IMPLICIT_CONSTRUCTORS(JitterFilter);
    288 };
    289 
    290 class ReorderFilter : public PacketProcessor {
    291  public:
    292   explicit ReorderFilter(PacketProcessorListener* listener);
    293   virtual ~ReorderFilter() {}
    294 
    295   void SetReorder(float reorder_percent);
    296   virtual void RunFor(int64_t time_ms, Packets* in_out);
    297 
    298  private:
    299   Random random_;
    300   float reorder_fraction_;
    301 
    302   DISALLOW_IMPLICIT_CONSTRUCTORS(ReorderFilter);
    303 };
    304 
    305 // Apply a bitrate choke with an infinite queue on the packet stream.
    306 class ChokeFilter : public PacketProcessor {
    307  public:
    308   explicit ChokeFilter(PacketProcessorListener* listener);
    309   ChokeFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
    310   virtual ~ChokeFilter();
    311 
    312   void SetCapacity(uint32_t kbps);
    313   void SetMaxDelay(int max_delay_ms);
    314   virtual void RunFor(int64_t time_ms, Packets* in_out);
    315 
    316   Stats<double> GetDelayStats() const;
    317 
    318  private:
    319   uint32_t kbps_;
    320   int64_t last_send_time_us_;
    321   scoped_ptr<DelayCapHelper> delay_cap_helper_;
    322 
    323   DISALLOW_IMPLICIT_CONSTRUCTORS(ChokeFilter);
    324 };
    325 
    326 class TraceBasedDeliveryFilter : public PacketProcessor {
    327  public:
    328   explicit TraceBasedDeliveryFilter(PacketProcessorListener* listener);
    329   TraceBasedDeliveryFilter(PacketProcessorListener* listener,
    330                            const std::string& name);
    331   virtual ~TraceBasedDeliveryFilter();
    332 
    333   // The file should contain nanosecond timestamps corresponding to the time
    334   // when the network can accept another packet. The timestamps should be
    335   // separated by new lines, e.g., "100000000\n125000000\n321000000\n..."
    336   bool Init(const std::string& filename);
    337   virtual void Plot(int64_t timestamp_ms);
    338   virtual void RunFor(int64_t time_ms, Packets* in_out);
    339 
    340   void SetMaxDelay(int max_delay_ms);
    341   Stats<double> GetDelayStats() const;
    342   Stats<double> GetBitrateStats() const;
    343 
    344  private:
    345   void ProceedToNextSlot();
    346 
    347   typedef std::vector<int64_t> TimeList;
    348   int64_t current_offset_us_;
    349   TimeList delivery_times_us_;
    350   TimeList::const_iterator next_delivery_it_;
    351   int64_t local_time_us_;
    352   scoped_ptr<RateCounter> rate_counter_;
    353   std::string name_;
    354   scoped_ptr<DelayCapHelper> delay_cap_helper_;
    355   Stats<double> packets_per_second_stats_;
    356   Stats<double> kbps_stats_;
    357 
    358   DISALLOW_COPY_AND_ASSIGN(TraceBasedDeliveryFilter);
    359 };
    360 
    361 class PacketSender : public PacketProcessor {
    362  public:
    363   struct Feedback {
    364     uint32_t estimated_bps;
    365   };
    366 
    367   explicit PacketSender(PacketProcessorListener* listener);
    368   PacketSender(PacketProcessorListener* listener, const FlowIds& flow_ids);
    369   virtual ~PacketSender() {}
    370 
    371   virtual uint32_t GetCapacityKbps() const { return 0; }
    372 
    373   // Call GiveFeedback() with the returned interval in milliseconds, provided
    374   // there is a new estimate available.
    375   // Note that changing the feedback interval affects the timing of when the
    376   // output of the estimators is sampled and therefore the baseline files may
    377   // have to be regenerated.
    378   virtual int GetFeedbackIntervalMs() const { return 1000; }
    379   virtual void GiveFeedback(const Feedback& feedback) {}
    380 
    381  private:
    382   DISALLOW_COPY_AND_ASSIGN(PacketSender);
    383 };
    384 
    385 class VideoSender : public PacketSender {
    386  public:
    387   VideoSender(int flow_id, PacketProcessorListener* listener, float fps,
    388               uint32_t kbps, uint32_t ssrc, float first_frame_offset);
    389   virtual ~VideoSender() {}
    390 
    391   uint32_t max_payload_size_bytes() const { return kMaxPayloadSizeBytes; }
    392   uint32_t bytes_per_second() const { return bytes_per_second_; }
    393 
    394   virtual uint32_t GetCapacityKbps() const;
    395 
    396   virtual void RunFor(int64_t time_ms, Packets* in_out);
    397 
    398  protected:
    399   const uint32_t kMaxPayloadSizeBytes;
    400   const uint32_t kTimestampBase;
    401   const double frame_period_ms_;
    402   uint32_t bytes_per_second_;
    403   uint32_t frame_size_bytes_;
    404 
    405  private:
    406   double next_frame_ms_;
    407   double now_ms_;
    408   RTPHeader prototype_header_;
    409 
    410   DISALLOW_IMPLICIT_CONSTRUCTORS(VideoSender);
    411 };
    412 
    413 class AdaptiveVideoSender : public VideoSender {
    414  public:
    415   AdaptiveVideoSender(int flow_id, PacketProcessorListener* listener,
    416                       float fps, uint32_t kbps, uint32_t ssrc,
    417                       float first_frame_offset);
    418   virtual ~AdaptiveVideoSender() {}
    419 
    420   virtual int GetFeedbackIntervalMs() const { return 100; }
    421   virtual void GiveFeedback(const Feedback& feedback);
    422 
    423 private:
    424   DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveVideoSender);
    425 };
    426 }  // namespace bwe
    427 }  // namespace testing
    428 }  // namespace webrtc
    429 
    430 #endif  // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FRAMEWORK_H_
    431