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
30namespace webrtc {
31namespace testing {
32namespace bwe {
33
34class DelayCapHelper;
35class RateCounter;
36
37
38typedef std::vector<int> FlowIds;
39const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids);
40
41template<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
133class 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
153class 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
178typedef std::list<Packet> Packets;
179typedef std::list<Packet>::iterator PacketsIt;
180typedef std::list<Packet>::const_iterator PacketsConstIt;
181
182bool IsTimeSorted(const Packets& packets);
183
184class PacketProcessor;
185
186class 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
195class 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
220class 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
247class 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
262class 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
277class 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
293class 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.
309class 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
329class 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
364class 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
388class 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
416class 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
430class 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