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