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