 Chromium Code Reviews
 Chromium Code Reviews Issue 1202253003:
  More Simulation Framework features  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 1202253003:
  More Simulation Framework features  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 
| 3 * | 3 * | 
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found | 
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may | 
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. | 
| 9 */ | 9 */ | 
| 10 | 10 | 
| 11 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h" | 11 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h" | 
| 12 | 12 | 
| 13 #include <stdio.h> | 13 #include <stdio.h> | 
| 14 | 14 | 
| 15 #include <sstream> | 15 #include <sstream> | 
| 16 | 16 | 
| 17 namespace webrtc { | 17 namespace webrtc { | 
| 18 namespace testing { | 18 namespace testing { | 
| 19 namespace bwe { | 19 namespace bwe { | 
| 20 | 20 | 
| 21 class DelayCapHelper { | 21 class DelayCapHelper { | 
| 22 public: | 22 public: | 
| 23 // Max delay = 0 stands for +infinite. | |
| 23 DelayCapHelper() : max_delay_us_(0), delay_stats_() {} | 24 DelayCapHelper() : max_delay_us_(0), delay_stats_() {} | 
| 24 | 25 | 
| 25 void SetMaxDelay(int max_delay_ms) { | 26 void SetMaxDelayMs(int64_t max_delay_ms) { | 
| 26 BWE_TEST_LOGGING_ENABLE(false); | 27 BWE_TEST_LOGGING_ENABLE(false); | 
| 27 BWE_TEST_LOGGING_LOG1("Max Delay", "%d ms", static_cast<int>(max_delay_ms)); | 28 BWE_TEST_LOGGING_LOG1("Max Delay", "%d ms", static_cast<int>(max_delay_ms)); | 
| 28 assert(max_delay_ms >= 0); | 29 assert(max_delay_ms >= 0); | 
| 29 max_delay_us_ = max_delay_ms * 1000; | 30 max_delay_us_ = max_delay_ms * 1000; | 
| 30 } | 31 } | 
| 31 | 32 | 
| 32 bool ShouldSendPacket(int64_t send_time_us, int64_t arrival_time_us) { | 33 bool ShouldSendPacket(int64_t send_time_us, int64_t arrival_time_us) { | 
| 33 int64_t packet_delay_us = send_time_us - arrival_time_us; | 34 int64_t packet_delay_us = send_time_us - arrival_time_us; | 
| 34 delay_stats_.Push(std::min(packet_delay_us, max_delay_us_) / 1000); | 35 delay_stats_.Push(std::min(packet_delay_us, max_delay_us_) / 1000); | 
| 35 return (max_delay_us_ == 0 || max_delay_us_ >= packet_delay_us); | 36 return (max_delay_us_ == 0 || max_delay_us_ >= packet_delay_us); | 
| 36 } | 37 } | 
| 37 | 38 | 
| 38 const Stats<double>& delay_stats() const { | 39 const Stats<double>& delay_stats() const { | 
| 39 return delay_stats_; | 40 return delay_stats_; | 
| 40 } | 41 } | 
| 41 | 42 | 
| 42 private: | 43 private: | 
| 43 int64_t max_delay_us_; | 44 int64_t max_delay_us_; | 
| 44 Stats<double> delay_stats_; | 45 Stats<double> delay_stats_; | 
| 45 | 46 | 
| 46 DISALLOW_COPY_AND_ASSIGN(DelayCapHelper); | 47 DISALLOW_COPY_AND_ASSIGN(DelayCapHelper); | 
| 47 }; | 48 }; | 
| 48 | 49 | 
| 49 const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids) { | 50 const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids) { | 
| 50 FlowIds flow_ids(&flow_ids_array[0], flow_ids_array + num_flow_ids); | 51 FlowIds flow_ids(&flow_ids_array[0], flow_ids_array + num_flow_ids); | 
| 51 return flow_ids; | 52 return flow_ids; | 
| 52 } | 53 } | 
| 53 | 54 | 
| 54 class RateCounter { | 55 const FlowIds CreateFlowIdRange(int initial_value, int last_value) { | 
| 55 public: | 56 int size = last_value - initial_value + 1; | 
| 56 RateCounter() | 57 assert(size > 0); | 
| 57 : kWindowSizeUs(1000000), | 58 int* flow_ids_array = new int[size]; | 
| 58 packets_per_second_(0), | 59 for (int i = initial_value; i <= last_value; ++i) { | 
| 59 bytes_per_second_(0), | 60 flow_ids_array[i - initial_value] = i; | 
| 60 last_accumulated_us_(0), | 61 } | 
| 61 window_() {} | 62 return CreateFlowIds(flow_ids_array, size); | 
| 63 } | |
| 62 | 64 | 
| 63 void UpdateRates(int64_t send_time_us, uint32_t payload_size) { | 65 void RateCounter::UpdateRates(int64_t send_time_us, uint32_t payload_size) { | 
| 64 packets_per_second_++; | 66 packets_per_second_++; | 
| 65 bytes_per_second_ += payload_size; | 67 recently_received_bytes += payload_size; | 
| 66 last_accumulated_us_ = send_time_us; | 68 last_accumulated_us_ = send_time_us; | 
| 67 window_.push_back(std::make_pair(send_time_us, payload_size)); | 69 window_.push_back(std::make_pair(send_time_us, payload_size)); | 
| 68 while (!window_.empty()) { | 70 while (!window_.empty()) { | 
| 69 const TimeSizePair& packet = window_.front(); | 71 const TimeSizePair& packet = window_.front(); | 
| 70 if (packet.first > (last_accumulated_us_ - kWindowSizeUs)) { | 72 if (packet.first > (last_accumulated_us_ - windows_size_us_)) { | 
| 71 break; | 73 break; | 
| 72 } | |
| 73 assert(packets_per_second_ >= 1); | |
| 74 assert(bytes_per_second_ >= packet.second); | |
| 75 packets_per_second_--; | |
| 76 bytes_per_second_ -= packet.second; | |
| 77 window_.pop_front(); | |
| 78 } | 74 } | 
| 75 assert(packets_per_second_ >= 1); | |
| 76 assert(recently_received_bytes >= packet.second); | |
| 77 packets_per_second_--; | |
| 78 recently_received_bytes -= packet.second; | |
| 79 window_.pop_front(); | |
| 79 } | 80 } | 
| 81 } | |
| 80 | 82 | 
| 81 uint32_t bits_per_second() const { | 83 uint32_t RateCounter::bits_per_second() const { | 
| 82 return bytes_per_second_ * 8; | 84 return (8 * 1000 * 1000 * recently_received_bytes) / windows_size_us_; | 
| 83 } | 85 } | 
| 84 | 86 | 
| 85 uint32_t packets_per_second() const { return packets_per_second_; } | 87 void RateCounter::set_windows_size_ms(int64_t windows_size_ms) { | 
| 86 | 88 windows_size_us_ = 1000 * windows_size_ms; | 
| 87 private: | 89 } | 
| 88 typedef std::pair<int64_t, uint32_t> TimeSizePair; | |
| 89 | |
| 90 const int64_t kWindowSizeUs; | |
| 91 uint32_t packets_per_second_; | |
| 92 uint32_t bytes_per_second_; | |
| 93 int64_t last_accumulated_us_; | |
| 94 std::list<TimeSizePair> window_; | |
| 95 }; | |
| 96 | 90 | 
| 97 Random::Random(uint32_t seed) | 91 Random::Random(uint32_t seed) | 
| 98 : a_(0x531FDB97 ^ seed), | 92 : a_(0x531FDB97 ^ seed), | 
| 99 b_(0x6420ECA8 + seed) { | 93 b_(0x6420ECA8 + seed) { | 
| 100 } | 94 } | 
| 101 | 95 | 
| 102 float Random::Rand() { | 96 float Random::Rand() { | 
| 103 const float kScale = 1.0f / 0xffffffff; | 97 const float kScale = 1.0f / 0xffffffff; | 
| 104 float result = kScale * b_; | 98 float result = kScale * b_; | 
| 105 a_ ^= b_; | 99 a_ ^= b_; | 
| 106 b_ += a_; | 100 b_ += a_; | 
| 107 return result; | 101 return result; | 
| 108 } | 102 } | 
| 109 | 103 | 
| 104 int Random::Rand(int low, int high) { | |
| 105 float uniform = Rand() * (high - low + 1) + low; | |
| 106 return static_cast<int>(uniform); | |
| 107 } | |
| 108 | |
| 110 int Random::Gaussian(int mean, int standard_deviation) { | 109 int Random::Gaussian(int mean, int standard_deviation) { | 
| 111 // Creating a Normal distribution variable from two independent uniform | 110 // Creating a Normal distribution variable from two independent uniform | 
| 112 // variables based on the Box-Muller transform, which is defined on the | 111 // variables based on the Box-Muller transform, which is defined on the | 
| 113 // interval (0, 1], hence the mask+add below. | 112 // interval (0, 1], hence the mask+add below. | 
| 114 const double kPi = 3.14159265358979323846; | 113 const double kPi = 3.14159265358979323846; | 
| 115 const double kScale = 1.0 / 0x80000000ul; | 114 const double kScale = 1.0 / 0x80000000ul; | 
| 116 double u1 = kScale * ((a_ & 0x7ffffffful) + 1); | 115 double u1 = kScale * ((a_ & 0x7ffffffful) + 1); | 
| 117 double u2 = kScale * ((b_ & 0x7ffffffful) + 1); | 116 double u2 = kScale * ((b_ & 0x7ffffffful) + 1); | 
| 118 a_ ^= b_; | 117 a_ ^= b_; | 
| 119 b_ += a_; | 118 b_ += a_; | 
| 120 return static_cast<int>(mean + standard_deviation * | 119 return static_cast<int>(mean + standard_deviation * | 
| 121 sqrt(-2 * log(u1)) * cos(2 * kPi * u2)); | 120 sqrt(-2 * log(u1)) * cos(2 * kPi * u2)); | 
| 122 } | 121 } | 
| 123 | 122 | 
| 123 int Random::Exponential(float lambda) { | |
| 124 float uniform = Rand(); | |
| 125 return static_cast<int>(-log(uniform) / lambda); | |
| 126 } | |
| 127 | |
| 124 Packet::Packet() | 128 Packet::Packet() | 
| 125 : flow_id_(0), creation_time_us_(-1), send_time_us_(-1), payload_size_(0) { | 129 : flow_id_(0), creation_time_us_(-1), send_time_us_(-1), payload_size_(0) { | 
| 126 } | 130 } | 
| 127 | 131 | 
| 128 Packet::Packet(int flow_id, int64_t send_time_us, size_t payload_size) | 132 Packet::Packet(int flow_id, int64_t send_time_us, size_t payload_size) | 
| 129 : flow_id_(flow_id), | 133 : flow_id_(flow_id), | 
| 130 creation_time_us_(send_time_us), | 134 creation_time_us_(send_time_us), | 
| 131 send_time_us_(send_time_us), | 135 send_time_us_(send_time_us), | 
| 132 payload_size_(payload_size) { | 136 payload_size_(payload_size) { | 
| 133 } | 137 } | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 return false; | 206 return false; | 
| 203 } | 207 } | 
| 204 last_it = it; | 208 last_it = it; | 
| 205 } | 209 } | 
| 206 return true; | 210 return true; | 
| 207 } | 211 } | 
| 208 | 212 | 
| 209 PacketProcessor::PacketProcessor(PacketProcessorListener* listener, | 213 PacketProcessor::PacketProcessor(PacketProcessorListener* listener, | 
| 210 int flow_id, | 214 int flow_id, | 
| 211 ProcessorType type) | 215 ProcessorType type) | 
| 212 : listener_(listener), flow_ids_(&flow_id, &flow_id + 1) { | 216 : rate_counter_(), listener_(listener), flow_ids_(&flow_id, &flow_id + 1) { | 
| 213 if (listener_) { | 217 if (listener_) { | 
| 214 listener_->AddPacketProcessor(this, type); | 218 listener_->AddPacketProcessor(this, type); | 
| 215 } | 219 } | 
| 216 } | 220 } | 
| 217 | 221 | 
| 218 PacketProcessor::PacketProcessor(PacketProcessorListener* listener, | 222 PacketProcessor::PacketProcessor(PacketProcessorListener* listener, | 
| 219 const FlowIds& flow_ids, | 223 const FlowIds& flow_ids, | 
| 220 ProcessorType type) | 224 ProcessorType type) | 
| 221 : listener_(listener), flow_ids_(flow_ids) { | 225 : rate_counter_(), listener_(listener), flow_ids_(flow_ids) { | 
| 
stefan-webrtc
2015/07/03 09:32:11
Actually no need to have rate_counter_() in the in
 
magalhaesc
2015/07/03 11:55:13
Done.
 | |
| 222 if (listener_) { | 226 if (listener_) { | 
| 223 listener_->AddPacketProcessor(this, type); | 227 listener_->AddPacketProcessor(this, type); | 
| 224 } | 228 } | 
| 225 } | 229 } | 
| 226 | 230 | 
| 227 PacketProcessor::~PacketProcessor() { | 231 PacketProcessor::~PacketProcessor() { | 
| 228 if (listener_) { | 232 if (listener_) { | 
| 229 listener_->RemovePacketProcessor(this); | 233 listener_->RemovePacketProcessor(this); | 
| 230 } | 234 } | 
| 231 } | 235 } | 
| 232 | 236 | 
| 237 uint32_t PacketProcessor::packets_per_second() const { | |
| 238 return rate_counter_.packets_per_second(); | |
| 239 } | |
| 240 | |
| 241 uint32_t PacketProcessor::bits_per_second() const { | |
| 242 return rate_counter_.bits_per_second(); | |
| 243 } | |
| 244 | |
| 233 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, | 245 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, | 
| 234 int flow_id, | 246 int flow_id, | 
| 235 const char* name) | 247 const char* name) | 
| 236 : PacketProcessor(listener, flow_id, kRegular), | 248 : PacketProcessor(listener, flow_id, kRegular), | 
| 237 rate_counter_(new RateCounter()), | |
| 238 packets_per_second_stats_(), | 249 packets_per_second_stats_(), | 
| 239 kbps_stats_(), | 250 kbps_stats_(), | 
| 240 name_() { | 251 name_(), | 
| 252 start_plotting_time_ms_(0) { | |
| 241 std::stringstream ss; | 253 std::stringstream ss; | 
| 242 ss << name << "_" << flow_id; | 254 ss << name << "_" << flow_id; | 
| 243 name_ = ss.str(); | 255 name_ = ss.str(); | 
| 244 } | 256 } | 
| 245 | 257 | 
| 246 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, | 258 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, | 
| 247 const FlowIds& flow_ids, | 259 const FlowIds& flow_ids, | 
| 248 const char* name) | 260 const char* name) | 
| 249 : PacketProcessor(listener, flow_ids, kRegular), | 261 : PacketProcessor(listener, flow_ids, kRegular), | 
| 250 rate_counter_(new RateCounter()), | |
| 251 packets_per_second_stats_(), | 262 packets_per_second_stats_(), | 
| 252 kbps_stats_(), | 263 kbps_stats_(), | 
| 253 name_() { | 264 name_(), | 
| 265 start_plotting_time_ms_(0) { | |
| 254 std::stringstream ss; | 266 std::stringstream ss; | 
| 255 ss << name << "_"; | 267 ss << name << "_"; | 
| 256 for (int flow_id : flow_ids) { | 268 for (int flow_id : flow_ids) { | 
| 257 ss << flow_id << ","; | 269 ss << flow_id << ","; | 
| 258 } | 270 } | 
| 259 name_ = ss.str(); | 271 name_ = ss.str(); | 
| 260 } | 272 } | 
| 261 | 273 | 
| 274 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, | |
| 275 const FlowIds& flow_ids, | |
| 276 const char* name, | |
| 277 int64_t start_plotting_time_ms) | |
| 278 : RateCounterFilter(listener, flow_ids, name) { | |
| 279 start_plotting_time_ms_ = start_plotting_time_ms; | |
| 280 } | |
| 281 | |
| 262 RateCounterFilter::~RateCounterFilter() { | 282 RateCounterFilter::~RateCounterFilter() { | 
| 263 LogStats(); | 283 LogStats(); | 
| 264 } | 284 } | 
| 265 | 285 | 
| 266 uint32_t RateCounterFilter::packets_per_second() const { | |
| 267 return rate_counter_->packets_per_second(); | |
| 268 } | |
| 269 | |
| 270 uint32_t RateCounterFilter::bits_per_second() const { | |
| 271 return rate_counter_->bits_per_second(); | |
| 272 } | |
| 273 | 286 | 
| 274 void RateCounterFilter::LogStats() { | 287 void RateCounterFilter::LogStats() { | 
| 275 BWE_TEST_LOGGING_CONTEXT("RateCounterFilter"); | 288 BWE_TEST_LOGGING_CONTEXT("RateCounterFilter"); | 
| 276 packets_per_second_stats_.Log("pps"); | 289 packets_per_second_stats_.Log("pps"); | 
| 277 kbps_stats_.Log("kbps"); | 290 kbps_stats_.Log("kbps"); | 
| 278 } | 291 } | 
| 279 | 292 | 
| 280 Stats<double> RateCounterFilter::GetBitrateStats() const { | 293 Stats<double> RateCounterFilter::GetBitrateStats() const { | 
| 281 return kbps_stats_; | 294 return kbps_stats_; | 
| 282 } | 295 } | 
| 283 | 296 | 
| 284 void RateCounterFilter::Plot(int64_t timestamp_ms) { | 297 void RateCounterFilter::Plot(int64_t timestamp_ms) { | 
| 298 uint32_t plot_kbps = 0; | |
| 299 if (timestamp_ms >= start_plotting_time_ms_) { | |
| 300 plot_kbps = rate_counter_.bits_per_second() / 1000.0; | |
| 301 } | |
| 285 BWE_TEST_LOGGING_CONTEXT(name_.c_str()); | 302 BWE_TEST_LOGGING_CONTEXT(name_.c_str()); | 
| 286 BWE_TEST_LOGGING_PLOT(0, "Throughput_#1", timestamp_ms, | 303 BWE_TEST_LOGGING_PLOT(0, "Throughput_#1", timestamp_ms, plot_kbps); | 
| 287 rate_counter_->bits_per_second() / 1000.0); | 304 RTC_UNUSED(plot_kbps); | 
| 288 } | 305 } | 
| 289 | 306 | 
| 290 void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 307 void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 
| 291 assert(in_out); | 308 assert(in_out); | 
| 292 for (const Packet* packet : *in_out) { | 309 for (const Packet* packet : *in_out) { | 
| 293 rate_counter_->UpdateRates(packet->send_time_us(), | 310 rate_counter_.UpdateRates(packet->send_time_us(), | 
| 294 static_cast<int>(packet->payload_size())); | 311 static_cast<int>(packet->payload_size())); | 
| 295 } | 312 } | 
| 296 packets_per_second_stats_.Push(rate_counter_->packets_per_second()); | 313 packets_per_second_stats_.Push(rate_counter_.packets_per_second()); | 
| 297 kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0); | 314 kbps_stats_.Push(rate_counter_.bits_per_second() / 1000.0); | 
| 298 } | 315 } | 
| 299 | 316 | 
| 300 LossFilter::LossFilter(PacketProcessorListener* listener, int flow_id) | 317 LossFilter::LossFilter(PacketProcessorListener* listener, int flow_id) | 
| 301 : PacketProcessor(listener, flow_id, kRegular), | 318 : PacketProcessor(listener, flow_id, kRegular), | 
| 302 random_(0x12345678), | 319 random_(0x12345678), | 
| 303 loss_fraction_(0.0f) { | 320 loss_fraction_(0.0f) { | 
| 304 } | 321 } | 
| 305 | 322 | 
| 306 LossFilter::LossFilter(PacketProcessorListener* listener, | 323 LossFilter::LossFilter(PacketProcessorListener* listener, | 
| 307 const FlowIds& flow_ids) | 324 const FlowIds& flow_ids) | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 323 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { | 340 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { | 
| 324 if (random_.Rand() < loss_fraction_) { | 341 if (random_.Rand() < loss_fraction_) { | 
| 325 delete *it; | 342 delete *it; | 
| 326 it = in_out->erase(it); | 343 it = in_out->erase(it); | 
| 327 } else { | 344 } else { | 
| 328 ++it; | 345 ++it; | 
| 329 } | 346 } | 
| 330 } | 347 } | 
| 331 } | 348 } | 
| 332 | 349 | 
| 350 const int64_t kDefaultOneWayDelayUs = 0; | |
| 351 | |
| 333 DelayFilter::DelayFilter(PacketProcessorListener* listener, int flow_id) | 352 DelayFilter::DelayFilter(PacketProcessorListener* listener, int flow_id) | 
| 334 : PacketProcessor(listener, flow_id, kRegular), | 353 : PacketProcessor(listener, flow_id, kRegular), | 
| 335 delay_us_(0), | 354 one_way_delay_us_(kDefaultOneWayDelayUs), | 
| 336 last_send_time_us_(0) { | 355 last_send_time_us_(0) { | 
| 337 } | 356 } | 
| 338 | 357 | 
| 339 DelayFilter::DelayFilter(PacketProcessorListener* listener, | 358 DelayFilter::DelayFilter(PacketProcessorListener* listener, | 
| 340 const FlowIds& flow_ids) | 359 const FlowIds& flow_ids) | 
| 341 : PacketProcessor(listener, flow_ids, kRegular), | 360 : PacketProcessor(listener, flow_ids, kRegular), | 
| 342 delay_us_(0), | 361 one_way_delay_us_(kDefaultOneWayDelayUs), | 
| 343 last_send_time_us_(0) { | 362 last_send_time_us_(0) { | 
| 344 } | 363 } | 
| 345 | 364 | 
| 346 void DelayFilter::SetDelayMs(int64_t delay_ms) { | 365 void DelayFilter::SetOneWayDelayMs(int64_t one_way_delay_ms) { | 
| 347 BWE_TEST_LOGGING_ENABLE(false); | 366 BWE_TEST_LOGGING_ENABLE(false); | 
| 348 BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast<int>(delay_ms)); | 367 BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast<int>(one_way_delay_ms)); | 
| 349 assert(delay_ms >= 0); | 368 assert(one_way_delay_ms >= 0); | 
| 350 delay_us_ = delay_ms * 1000; | 369 one_way_delay_us_ = one_way_delay_ms * 1000; | 
| 351 } | 370 } | 
| 352 | 371 | 
| 353 void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 372 void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 
| 354 assert(in_out); | 373 assert(in_out); | 
| 355 for (Packet* packet : *in_out) { | 374 for (Packet* packet : *in_out) { | 
| 356 int64_t new_send_time_us = packet->send_time_us() + delay_us_; | 375 int64_t new_send_time_us = packet->send_time_us() + one_way_delay_us_; | 
| 357 last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us); | 376 last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us); | 
| 358 packet->set_send_time_us(last_send_time_us_); | 377 packet->set_send_time_us(last_send_time_us_); | 
| 359 } | 378 } | 
| 360 } | 379 } | 
| 361 | 380 | 
| 362 JitterFilter::JitterFilter(PacketProcessorListener* listener, int flow_id) | 381 JitterFilter::JitterFilter(PacketProcessorListener* listener, int flow_id) | 
| 363 : PacketProcessor(listener, flow_id, kRegular), | 382 : PacketProcessor(listener, flow_id, kRegular), | 
| 364 random_(0x89674523), | 383 random_(0x89674523), | 
| 365 stddev_jitter_us_(0), | 384 stddev_jitter_us_(0), | 
| 366 last_send_time_us_(0) { | 385 last_send_time_us_(0) { | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 int64_t t2 = (*it)->send_time_us(); | 443 int64_t t2 = (*it)->send_time_us(); | 
| 425 std::swap(*last_it, *it); | 444 std::swap(*last_it, *it); | 
| 426 (*last_it)->set_send_time_us(t1); | 445 (*last_it)->set_send_time_us(t1); | 
| 427 (*it)->set_send_time_us(t2); | 446 (*it)->set_send_time_us(t2); | 
| 428 } | 447 } | 
| 429 last_it = it; | 448 last_it = it; | 
| 430 } | 449 } | 
| 431 } | 450 } | 
| 432 } | 451 } | 
| 433 | 452 | 
| 453 const uint32_t kDefaultKbps = 1200; | |
| 454 | |
| 434 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, int flow_id) | 455 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, int flow_id) | 
| 435 : PacketProcessor(listener, flow_id, kRegular), | 456 : PacketProcessor(listener, flow_id, kRegular), | 
| 436 kbps_(1200), | 457 capacity_kbps_(kDefaultKbps), | 
| 437 last_send_time_us_(0), | 458 last_send_time_us_(0), | 
| 438 delay_cap_helper_(new DelayCapHelper()) { | 459 delay_cap_helper_(new DelayCapHelper()) { | 
| 439 } | 460 } | 
| 440 | 461 | 
| 441 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, | 462 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, | 
| 442 const FlowIds& flow_ids) | 463 const FlowIds& flow_ids) | 
| 443 : PacketProcessor(listener, flow_ids, kRegular), | 464 : PacketProcessor(listener, flow_ids, kRegular), | 
| 444 kbps_(1200), | 465 capacity_kbps_(kDefaultKbps), | 
| 445 last_send_time_us_(0), | 466 last_send_time_us_(0), | 
| 446 delay_cap_helper_(new DelayCapHelper()) { | 467 delay_cap_helper_(new DelayCapHelper()) { | 
| 447 } | 468 } | 
| 448 | 469 | 
| 449 ChokeFilter::~ChokeFilter() {} | 470 ChokeFilter::~ChokeFilter() {} | 
| 450 | 471 | 
| 451 void ChokeFilter::SetCapacity(uint32_t kbps) { | 472 void ChokeFilter::set_capacity_kbps(uint32_t kbps) { | 
| 452 BWE_TEST_LOGGING_ENABLE(false); | 473 BWE_TEST_LOGGING_ENABLE(false); | 
| 453 BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps); | 474 BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps); | 
| 454 kbps_ = kbps; | 475 capacity_kbps_ = kbps; | 
| 476 } | |
| 477 | |
| 478 uint32_t ChokeFilter::capacity_kbps() { | |
| 479 return capacity_kbps_; | |
| 455 } | 480 } | 
| 456 | 481 | 
| 457 void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 482 void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 
| 458 assert(in_out); | 483 assert(in_out); | 
| 459 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { | 484 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { | 
| 460 int64_t earliest_send_time_us = | 485 int64_t earliest_send_time_us = | 
| 461 last_send_time_us_ + | 486 last_send_time_us_ + | 
| 462 ((*it)->payload_size() * 8 * 1000 + kbps_ / 2) / kbps_; | 487 ((*it)->payload_size() * 8 * 1000 + capacity_kbps_ / 2) / | 
| 488 capacity_kbps_; | |
| 489 | |
| 463 int64_t new_send_time_us = | 490 int64_t new_send_time_us = | 
| 464 std::max((*it)->send_time_us(), earliest_send_time_us); | 491 std::max((*it)->send_time_us(), earliest_send_time_us); | 
| 492 | |
| 465 if (delay_cap_helper_->ShouldSendPacket(new_send_time_us, | 493 if (delay_cap_helper_->ShouldSendPacket(new_send_time_us, | 
| 466 (*it)->send_time_us())) { | 494 (*it)->send_time_us())) { | 
| 467 (*it)->set_send_time_us(new_send_time_us); | 495 (*it)->set_send_time_us(new_send_time_us); | 
| 468 last_send_time_us_ = new_send_time_us; | 496 last_send_time_us_ = new_send_time_us; | 
| 469 ++it; | 497 ++it; | 
| 470 } else { | 498 } else { | 
| 471 delete *it; | 499 delete *it; | 
| 472 it = in_out->erase(it); | 500 it = in_out->erase(it); | 
| 473 } | 501 } | 
| 474 } | 502 } | 
| 475 } | 503 } | 
| 476 | 504 | 
| 477 void ChokeFilter::SetMaxDelay(int max_delay_ms) { | 505 void ChokeFilter::SetMaxDelayMs(int64_t max_delay_ms) { | 
| 478 delay_cap_helper_->SetMaxDelay(max_delay_ms); | 506 delay_cap_helper_->SetMaxDelayMs(max_delay_ms); | 
| 479 } | 507 } | 
| 480 | 508 | 
| 481 Stats<double> ChokeFilter::GetDelayStats() const { | 509 Stats<double> ChokeFilter::GetDelayStats() const { | 
| 482 return delay_cap_helper_->delay_stats(); | 510 return delay_cap_helper_->delay_stats(); | 
| 483 } | 511 } | 
| 484 | 512 | 
| 485 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( | 513 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( | 
| 486 PacketProcessorListener* listener, | 514 PacketProcessorListener* listener, | 
| 487 int flow_id) | 515 int flow_id) | 
| 488 : PacketProcessor(listener, flow_id, kRegular), | 516 : PacketProcessor(listener, flow_id, kRegular), | 
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 585 if (local_time_us_ >= (*it)->send_time_us()) { | 613 if (local_time_us_ >= (*it)->send_time_us()) { | 
| 586 (*it)->set_send_time_us(local_time_us_); | 614 (*it)->set_send_time_us(local_time_us_); | 
| 587 ProceedToNextSlot(); | 615 ProceedToNextSlot(); | 
| 588 } | 616 } | 
| 589 ++it; | 617 ++it; | 
| 590 } | 618 } | 
| 591 packets_per_second_stats_.Push(rate_counter_->packets_per_second()); | 619 packets_per_second_stats_.Push(rate_counter_->packets_per_second()); | 
| 592 kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0); | 620 kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0); | 
| 593 } | 621 } | 
| 594 | 622 | 
| 595 void TraceBasedDeliveryFilter::SetMaxDelay(int max_delay_ms) { | 623 void TraceBasedDeliveryFilter::SetMaxDelayMs(int64_t max_delay_ms) { | 
| 596 delay_cap_helper_->SetMaxDelay(max_delay_ms); | 624 delay_cap_helper_->SetMaxDelayMs(max_delay_ms); | 
| 597 } | 625 } | 
| 598 | 626 | 
| 599 Stats<double> TraceBasedDeliveryFilter::GetDelayStats() const { | 627 Stats<double> TraceBasedDeliveryFilter::GetDelayStats() const { | 
| 600 return delay_cap_helper_->delay_stats(); | 628 return delay_cap_helper_->delay_stats(); | 
| 601 } | 629 } | 
| 602 | 630 | 
| 603 Stats<double> TraceBasedDeliveryFilter::GetBitrateStats() const { | 631 Stats<double> TraceBasedDeliveryFilter::GetBitrateStats() const { | 
| 604 return kbps_stats_; | 632 return kbps_stats_; | 
| 605 } | 633 } | 
| 606 | 634 | 
| (...skipping 17 matching lines...) Expand all Loading... | |
| 624 VideoSource::VideoSource(int flow_id, | 652 VideoSource::VideoSource(int flow_id, | 
| 625 float fps, | 653 float fps, | 
| 626 uint32_t kbps, | 654 uint32_t kbps, | 
| 627 uint32_t ssrc, | 655 uint32_t ssrc, | 
| 628 int64_t first_frame_offset_ms) | 656 int64_t first_frame_offset_ms) | 
| 629 : kMaxPayloadSizeBytes(1200), | 657 : kMaxPayloadSizeBytes(1200), | 
| 630 kTimestampBase(0xff80ff00ul), | 658 kTimestampBase(0xff80ff00ul), | 
| 631 frame_period_ms_(1000.0 / fps), | 659 frame_period_ms_(1000.0 / fps), | 
| 632 bits_per_second_(1000 * kbps), | 660 bits_per_second_(1000 * kbps), | 
| 633 frame_size_bytes_(bits_per_second_ / 8 / fps), | 661 frame_size_bytes_(bits_per_second_ / 8 / fps), | 
| 662 running_(true), | |
| 634 flow_id_(flow_id), | 663 flow_id_(flow_id), | 
| 635 next_frame_ms_(first_frame_offset_ms), | 664 next_frame_ms_(first_frame_offset_ms), | 
| 636 now_ms_(0), | 665 now_ms_(0), | 
| 637 prototype_header_() { | 666 prototype_header_(), | 
| 667 start_plotting_ms_(first_frame_offset_ms) { | |
| 638 memset(&prototype_header_, 0, sizeof(prototype_header_)); | 668 memset(&prototype_header_, 0, sizeof(prototype_header_)); | 
| 639 prototype_header_.ssrc = ssrc; | 669 prototype_header_.ssrc = ssrc; | 
| 640 prototype_header_.sequenceNumber = 0xf000u; | 670 prototype_header_.sequenceNumber = 0xf000u; | 
| 641 } | 671 } | 
| 642 | 672 | 
| 643 uint32_t VideoSource::NextFrameSize() { | 673 uint32_t VideoSource::NextFrameSize() { | 
| 644 return frame_size_bytes_; | 674 return frame_size_bytes_; | 
| 645 } | 675 } | 
| 646 | 676 | 
| 647 uint32_t VideoSource::NextPacketSize(uint32_t frame_size, | 677 uint32_t VideoSource::NextPacketSize(uint32_t frame_size, | 
| 648 uint32_t remaining_payload) { | 678 uint32_t remaining_payload) { | 
| 649 return std::min(kMaxPayloadSizeBytes, remaining_payload); | 679 return std::min(kMaxPayloadSizeBytes, remaining_payload); | 
| 650 } | 680 } | 
| 651 | 681 | 
| 652 void VideoSource::RunFor(int64_t time_ms, Packets* in_out) { | 682 void VideoSource::RunFor(int64_t time_ms, Packets* in_out) { | 
| 653 assert(in_out); | 683 assert(in_out); | 
| 654 std::stringstream ss; | 684 | 
| 655 ss << "SendEstimate_" << flow_id_ << "#1"; | |
| 656 BWE_TEST_LOGGING_PLOT(0, ss.str(), now_ms_, bits_per_second_ / 1000); | |
| 657 now_ms_ += time_ms; | 685 now_ms_ += time_ms; | 
| 658 Packets new_packets; | 686 Packets new_packets; | 
| 687 | |
| 659 while (now_ms_ >= next_frame_ms_) { | 688 while (now_ms_ >= next_frame_ms_) { | 
| 660 prototype_header_.timestamp = kTimestampBase + | 689 prototype_header_.timestamp = kTimestampBase + | 
| 661 static_cast<uint32_t>(next_frame_ms_ * 90.0); | 690 static_cast<uint32_t>(next_frame_ms_ * 90.0); | 
| 662 prototype_header_.extension.transmissionTimeOffset = 0; | 691 prototype_header_.extension.transmissionTimeOffset = 0; | 
| 663 | 692 | 
| 664 // Generate new packets for this frame, all with the same timestamp, | 693 // Generate new packets for this frame, all with the same timestamp, | 
| 665 // but the payload size is capped, so if the whole frame doesn't fit in | 694 // but the payload size is capped, so if the whole frame doesn't fit in | 
| 666 // one packet, we will see a number of equally sized packets followed by | 695 // one packet, we will see a number of equally sized packets followed by | 
| 667 // one smaller at the tail. | 696 // one smaller at the tail. | 
| 697 | |
| 668 int64_t send_time_us = next_frame_ms_ * 1000.0; | 698 int64_t send_time_us = next_frame_ms_ * 1000.0; | 
| 669 uint32_t frame_size = NextFrameSize(); | |
| 670 uint32_t payload_size = frame_size; | |
| 671 | 699 | 
| 672 while (payload_size > 0) { | 700 if (running_) { | 
| 673 ++prototype_header_.sequenceNumber; | 701 uint32_t frame_size = NextFrameSize(); | 
| 674 uint32_t size = NextPacketSize(frame_size, payload_size); | 702 uint32_t payload_size = frame_size; | 
| 675 MediaPacket* new_packet = | 703 | 
| 676 new MediaPacket(flow_id_, send_time_us, size, prototype_header_); | 704 while (payload_size > 0) { | 
| 677 new_packets.push_back(new_packet); | 705 ++prototype_header_.sequenceNumber; | 
| 678 new_packet->SetAbsSendTimeMs(next_frame_ms_); | 706 uint32_t size = NextPacketSize(frame_size, payload_size); | 
| 679 new_packet->set_sender_timestamp_us(send_time_us); | 707 MediaPacket* new_packet = | 
| 680 payload_size -= size; | 708 new MediaPacket(flow_id_, send_time_us, size, prototype_header_); | 
| 709 new_packets.push_back(new_packet); | |
| 710 new_packet->SetAbsSendTimeMs(next_frame_ms_); | |
| 711 new_packet->set_sender_timestamp_us(send_time_us); | |
| 712 payload_size -= size; | |
| 713 } | |
| 681 } | 714 } | 
| 682 | 715 | 
| 683 next_frame_ms_ += frame_period_ms_; | 716 // A variance picked uniformly from {-1, 0, 1} ms is added to the frame | 
| 717 // timestamp. | |
| 718 next_frame_ms_ += | |
| 719 frame_period_ms_ - 1 + 2 * static_cast<float>(rand()) / RAND_MAX; | |
| 684 } | 720 } | 
| 721 | |
| 685 in_out->merge(new_packets, DereferencingComparator<Packet>); | 722 in_out->merge(new_packets, DereferencingComparator<Packet>); | 
| 686 } | 723 } | 
| 687 | 724 | 
| 725 void VideoSource::Pause() { | |
| 726 running_ = false; | |
| 727 } | |
| 728 | |
| 729 void VideoSource::Resume() { | |
| 730 running_ = true; | |
| 731 } | |
| 732 | |
| 733 void AdaptiveVideoSource::SetBitrateBps(int bitrate_bps) { | |
| 734 if (!running_) { | |
| 735 bitrate_bps = 0; | |
| 736 } | |
| 737 bits_per_second_ = std::min(bitrate_bps, 2500000); | |
| 738 frame_size_bytes_ = (bits_per_second_ / 8 * frame_period_ms_ + 500) / 1000; | |
| 739 } | |
| 740 | |
| 688 AdaptiveVideoSource::AdaptiveVideoSource(int flow_id, | 741 AdaptiveVideoSource::AdaptiveVideoSource(int flow_id, | 
| 689 float fps, | 742 float fps, | 
| 690 uint32_t kbps, | 743 uint32_t kbps, | 
| 691 uint32_t ssrc, | 744 uint32_t ssrc, | 
| 692 int64_t first_frame_offset_ms) | 745 int64_t first_frame_offset_ms) | 
| 693 : VideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms) { | 746 : VideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms) { | 
| 694 } | 747 } | 
| 695 | 748 | 
| 696 void AdaptiveVideoSource::SetBitrateBps(int bitrate_bps) { | |
| 697 bits_per_second_ = std::min(bitrate_bps, 2500000); | |
| 698 frame_size_bytes_ = (bits_per_second_ / 8 * frame_period_ms_ + 500) / 1000; | |
| 699 } | |
| 700 | |
| 701 PeriodicKeyFrameSource::PeriodicKeyFrameSource(int flow_id, | 749 PeriodicKeyFrameSource::PeriodicKeyFrameSource(int flow_id, | 
| 702 float fps, | 750 float fps, | 
| 703 uint32_t kbps, | 751 uint32_t kbps, | 
| 704 uint32_t ssrc, | 752 uint32_t ssrc, | 
| 705 int64_t first_frame_offset_ms, | 753 int64_t first_frame_offset_ms, | 
| 706 int key_frame_interval) | 754 int key_frame_interval) | 
| 707 : AdaptiveVideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms), | 755 : AdaptiveVideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms), | 
| 708 key_frame_interval_(key_frame_interval), | 756 key_frame_interval_(key_frame_interval), | 
| 709 frame_counter_(0), | 757 frame_counter_(0), | 
| 710 compensation_bytes_(0), | 758 compensation_bytes_(0), | 
| (...skipping 30 matching lines...) Expand all Loading... | |
| 741 uint32_t PeriodicKeyFrameSource::NextPacketSize(uint32_t frame_size, | 789 uint32_t PeriodicKeyFrameSource::NextPacketSize(uint32_t frame_size, | 
| 742 uint32_t remaining_payload) { | 790 uint32_t remaining_payload) { | 
| 743 uint32_t fragments = | 791 uint32_t fragments = | 
| 744 (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes; | 792 (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes; | 
| 745 uint32_t avg_size = (frame_size + fragments - 1) / fragments; | 793 uint32_t avg_size = (frame_size + fragments - 1) / fragments; | 
| 746 return std::min(avg_size, remaining_payload); | 794 return std::min(avg_size, remaining_payload); | 
| 747 } | 795 } | 
| 748 } // namespace bwe | 796 } // namespace bwe | 
| 749 } // namespace testing | 797 } // namespace testing | 
| 750 } // namespace webrtc | 798 } // namespace webrtc | 
| OLD | NEW |