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