Chromium Code Reviews| 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 set_max_delay_ms(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 ++recently_received_packets_; |
| 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_ - window_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(recently_received_packets_ >= 1); | |
| 76 assert(recently_received_bytes_ >= packet.second); | |
| 77 --recently_received_packets_; | |
| 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 * recently_received_bytes_) / BitrateWindowS(); |
| 83 } | 85 } |
| 84 | 86 |
| 85 uint32_t packets_per_second() const { return packets_per_second_; } | 87 uint32_t RateCounter::packets_per_second() const { |
| 88 return recently_received_packets_ / BitrateWindowS(); | |
| 89 } | |
| 86 | 90 |
| 87 private: | 91 double RateCounter::BitrateWindowS() const { |
| 88 typedef std::pair<int64_t, uint32_t> TimeSizePair; | 92 return static_cast<double>(window_size_us_) / (1000 * 1000); |
| 93 } | |
| 89 | 94 |
| 90 const int64_t kWindowSizeUs; | 95 Random::Random(uint32_t seed) : a_(0x531FDB97 ^ seed), b_(0x6420ECA8 + seed) { |
| 91 uint32_t packets_per_second_; | 96 } |
| 92 uint32_t bytes_per_second_; | 97 |
| 93 int64_t last_accumulated_us_; | 98 float Random::Rand() { |
| 94 std::list<TimeSizePair> window_; | 99 const float kScale = 1.0f / 0xffffffff; |
| 95 }; | 100 float result = kScale * b_; |
| 101 a_ ^= b_; | |
| 102 b_ += a_; | |
| 103 return result; | |
| 104 } | |
| 105 | |
| 106 int Random::Rand(int low, int high) { | |
| 107 float uniform = Rand() * (high - low + 1) + low; | |
| 108 return static_cast<int>(uniform); | |
| 109 } | |
| 110 | |
| 111 int Random::Gaussian(int mean, int standard_deviation) { | |
| 112 // Creating a Normal distribution variable from two independent uniform | |
| 113 // variables based on the Box-Muller transform, which is defined on the | |
| 114 // interval (0, 1], hence the mask+add below. | |
| 115 const double kPi = 3.14159265358979323846; | |
| 116 const double kScale = 1.0 / 0x80000000ul; | |
| 117 double u1 = kScale * ((a_ & 0x7ffffffful) + 1); | |
| 118 double u2 = kScale * ((b_ & 0x7ffffffful) + 1); | |
| 119 a_ ^= b_; | |
| 120 b_ += a_; | |
| 121 return static_cast<int>( | |
| 122 mean + standard_deviation * sqrt(-2 * log(u1)) * cos(2 * kPi * u2)); | |
| 123 } | |
| 124 | |
| 125 int Random::Exponential(float lambda) { | |
| 126 float uniform = Rand(); | |
| 127 return static_cast<int>(-log(uniform) / lambda); | |
| 128 } | |
| 96 | 129 |
| 97 Packet::Packet() | 130 Packet::Packet() |
| 98 : flow_id_(0), creation_time_us_(-1), send_time_us_(-1), payload_size_(0) { | 131 : flow_id_(0), creation_time_us_(-1), send_time_us_(-1), payload_size_(0) { |
| 99 } | 132 } |
| 100 | 133 |
| 101 Packet::Packet(int flow_id, int64_t send_time_us, size_t payload_size) | 134 Packet::Packet(int flow_id, int64_t send_time_us, size_t payload_size) |
| 102 : flow_id_(flow_id), | 135 : flow_id_(flow_id), |
| 103 creation_time_us_(send_time_us), | 136 creation_time_us_(send_time_us), |
| 104 send_time_us_(send_time_us), | 137 send_time_us_(send_time_us), |
| 105 payload_size_(payload_size) { | 138 payload_size_(payload_size) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 listener_->AddPacketProcessor(this, type); | 229 listener_->AddPacketProcessor(this, type); |
| 197 } | 230 } |
| 198 } | 231 } |
| 199 | 232 |
| 200 PacketProcessor::~PacketProcessor() { | 233 PacketProcessor::~PacketProcessor() { |
| 201 if (listener_) { | 234 if (listener_) { |
| 202 listener_->RemovePacketProcessor(this); | 235 listener_->RemovePacketProcessor(this); |
| 203 } | 236 } |
| 204 } | 237 } |
| 205 | 238 |
| 239 uint32_t PacketProcessor::packets_per_second() const { | |
| 240 return rate_counter_.packets_per_second(); | |
| 241 } | |
| 242 | |
| 243 uint32_t PacketProcessor::bits_per_second() const { | |
| 244 return rate_counter_.bits_per_second(); | |
| 245 } | |
| 246 | |
| 206 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, | 247 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, |
| 207 int flow_id, | 248 int flow_id, |
| 208 const char* name) | 249 const char* name) |
| 209 : PacketProcessor(listener, flow_id, kRegular), | 250 : PacketProcessor(listener, flow_id, kRegular), |
| 210 rate_counter_(new RateCounter()), | |
| 211 packets_per_second_stats_(), | 251 packets_per_second_stats_(), |
| 212 kbps_stats_(), | 252 kbps_stats_(), |
| 213 name_() { | 253 name_(), |
| 254 start_plotting_time_ms_(0) { | |
| 214 std::stringstream ss; | 255 std::stringstream ss; |
| 215 ss << name << "_" << flow_id; | 256 ss << name << "_" << flow_id; |
| 216 name_ = ss.str(); | 257 name_ = ss.str(); |
| 217 } | 258 } |
| 218 | 259 |
| 219 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, | 260 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, |
| 220 const FlowIds& flow_ids, | 261 const FlowIds& flow_ids, |
| 221 const char* name) | 262 const char* name) |
| 222 : PacketProcessor(listener, flow_ids, kRegular), | 263 : PacketProcessor(listener, flow_ids, kRegular), |
| 223 rate_counter_(new RateCounter()), | |
| 224 packets_per_second_stats_(), | 264 packets_per_second_stats_(), |
| 225 kbps_stats_(), | 265 kbps_stats_(), |
| 226 name_() { | 266 name_(), |
| 267 start_plotting_time_ms_(0) { | |
| 227 std::stringstream ss; | 268 std::stringstream ss; |
| 228 ss << name << "_"; | 269 ss << name << "_"; |
| 229 for (int flow_id : flow_ids) { | 270 for (int flow_id : flow_ids) { |
| 230 ss << flow_id << ","; | 271 ss << flow_id << ","; |
| 231 } | 272 } |
| 232 name_ = ss.str(); | 273 name_ = ss.str(); |
| 233 } | 274 } |
| 234 | 275 |
| 276 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, | |
| 277 const FlowIds& flow_ids, | |
| 278 const char* name, | |
| 279 int64_t start_plotting_time_ms) | |
| 280 : RateCounterFilter(listener, flow_ids, name) { | |
| 281 start_plotting_time_ms_ = start_plotting_time_ms; | |
| 282 } | |
| 283 | |
| 235 RateCounterFilter::~RateCounterFilter() { | 284 RateCounterFilter::~RateCounterFilter() { |
| 236 LogStats(); | 285 LogStats(); |
| 237 } | 286 } |
| 238 | 287 |
| 239 uint32_t RateCounterFilter::packets_per_second() const { | |
| 240 return rate_counter_->packets_per_second(); | |
| 241 } | |
| 242 | |
| 243 uint32_t RateCounterFilter::bits_per_second() const { | |
| 244 return rate_counter_->bits_per_second(); | |
| 245 } | |
| 246 | 288 |
| 247 void RateCounterFilter::LogStats() { | 289 void RateCounterFilter::LogStats() { |
| 248 BWE_TEST_LOGGING_CONTEXT("RateCounterFilter"); | 290 BWE_TEST_LOGGING_CONTEXT("RateCounterFilter"); |
| 249 packets_per_second_stats_.Log("pps"); | 291 packets_per_second_stats_.Log("pps"); |
| 250 kbps_stats_.Log("kbps"); | 292 kbps_stats_.Log("kbps"); |
| 251 } | 293 } |
| 252 | 294 |
| 253 Stats<double> RateCounterFilter::GetBitrateStats() const { | 295 Stats<double> RateCounterFilter::GetBitrateStats() const { |
| 254 return kbps_stats_; | 296 return kbps_stats_; |
| 255 } | 297 } |
| 256 | 298 |
| 257 void RateCounterFilter::Plot(int64_t timestamp_ms) { | 299 void RateCounterFilter::Plot(int64_t timestamp_ms) { |
| 300 uint32_t plot_kbps = 0; | |
| 301 if (timestamp_ms >= start_plotting_time_ms_) { | |
| 302 plot_kbps = rate_counter_.bits_per_second() / 1000.0; | |
| 303 } | |
| 258 BWE_TEST_LOGGING_CONTEXT(name_.c_str()); | 304 BWE_TEST_LOGGING_CONTEXT(name_.c_str()); |
| 259 BWE_TEST_LOGGING_PLOT(0, "Throughput_#1", timestamp_ms, | 305 BWE_TEST_LOGGING_PLOT(0, "Throughput_#1", timestamp_ms, plot_kbps); |
| 260 rate_counter_->bits_per_second() / 1000.0); | 306 RTC_UNUSED(plot_kbps); |
| 261 } | 307 } |
| 262 | 308 |
| 263 void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 309 void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { |
| 264 assert(in_out); | 310 assert(in_out); |
| 265 for (const Packet* packet : *in_out) { | 311 for (const Packet* packet : *in_out) { |
| 266 rate_counter_->UpdateRates(packet->send_time_us(), | 312 rate_counter_.UpdateRates(packet->send_time_us(), |
| 267 static_cast<int>(packet->payload_size())); | 313 static_cast<int>(packet->payload_size())); |
| 268 } | 314 } |
| 269 packets_per_second_stats_.Push(rate_counter_->packets_per_second()); | 315 packets_per_second_stats_.Push(rate_counter_.packets_per_second()); |
| 270 kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0); | 316 kbps_stats_.Push(rate_counter_.bits_per_second() / 1000.0); |
| 271 } | 317 } |
| 272 | 318 |
| 273 LossFilter::LossFilter(PacketProcessorListener* listener, int flow_id) | 319 LossFilter::LossFilter(PacketProcessorListener* listener, int flow_id) |
| 274 : PacketProcessor(listener, flow_id, kRegular), | 320 : PacketProcessor(listener, flow_id, kRegular), |
| 275 random_(0x12345678), | 321 random_(0x12345678), |
| 276 loss_fraction_(0.0f) { | 322 loss_fraction_(0.0f) { |
| 277 } | 323 } |
| 278 | 324 |
| 279 LossFilter::LossFilter(PacketProcessorListener* listener, | 325 LossFilter::LossFilter(PacketProcessorListener* listener, |
| 280 const FlowIds& flow_ids) | 326 const FlowIds& flow_ids) |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 296 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { | 342 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { |
| 297 if (random_.Rand() < loss_fraction_) { | 343 if (random_.Rand() < loss_fraction_) { |
| 298 delete *it; | 344 delete *it; |
| 299 it = in_out->erase(it); | 345 it = in_out->erase(it); |
| 300 } else { | 346 } else { |
| 301 ++it; | 347 ++it; |
| 302 } | 348 } |
| 303 } | 349 } |
| 304 } | 350 } |
| 305 | 351 |
| 352 const int64_t kDefaultOneWayDelayUs = 0; | |
| 353 | |
| 306 DelayFilter::DelayFilter(PacketProcessorListener* listener, int flow_id) | 354 DelayFilter::DelayFilter(PacketProcessorListener* listener, int flow_id) |
| 307 : PacketProcessor(listener, flow_id, kRegular), | 355 : PacketProcessor(listener, flow_id, kRegular), |
| 308 delay_us_(0), | 356 one_way_delay_us_(kDefaultOneWayDelayUs), |
| 309 last_send_time_us_(0) { | 357 last_send_time_us_(0) { |
| 310 } | 358 } |
| 311 | 359 |
| 312 DelayFilter::DelayFilter(PacketProcessorListener* listener, | 360 DelayFilter::DelayFilter(PacketProcessorListener* listener, |
| 313 const FlowIds& flow_ids) | 361 const FlowIds& flow_ids) |
| 314 : PacketProcessor(listener, flow_ids, kRegular), | 362 : PacketProcessor(listener, flow_ids, kRegular), |
| 315 delay_us_(0), | 363 one_way_delay_us_(kDefaultOneWayDelayUs), |
| 316 last_send_time_us_(0) { | 364 last_send_time_us_(0) { |
| 317 } | 365 } |
| 318 | 366 |
| 319 void DelayFilter::SetDelayMs(int64_t delay_ms) { | 367 void DelayFilter::SetOneWayDelayMs(int64_t one_way_delay_ms) { |
| 320 BWE_TEST_LOGGING_ENABLE(false); | 368 BWE_TEST_LOGGING_ENABLE(false); |
| 321 BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast<int>(delay_ms)); | 369 BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast<int>(one_way_delay_ms)); |
| 322 assert(delay_ms >= 0); | 370 assert(one_way_delay_ms >= 0); |
| 323 delay_us_ = delay_ms * 1000; | 371 one_way_delay_us_ = one_way_delay_ms * 1000; |
| 324 } | 372 } |
| 325 | 373 |
| 326 void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 374 void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { |
| 327 assert(in_out); | 375 assert(in_out); |
| 328 for (Packet* packet : *in_out) { | 376 for (Packet* packet : *in_out) { |
| 329 int64_t new_send_time_us = packet->send_time_us() + delay_us_; | 377 int64_t new_send_time_us = packet->send_time_us() + one_way_delay_us_; |
| 330 last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us); | 378 last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us); |
| 331 packet->set_send_time_us(last_send_time_us_); | 379 packet->set_send_time_us(last_send_time_us_); |
| 332 } | 380 } |
| 333 } | 381 } |
| 334 | 382 |
| 335 JitterFilter::JitterFilter(PacketProcessorListener* listener, int flow_id) | 383 JitterFilter::JitterFilter(PacketProcessorListener* listener, int flow_id) |
| 336 : PacketProcessor(listener, flow_id, kRegular), | 384 : PacketProcessor(listener, flow_id, kRegular), |
| 337 random_(0x89674523), | 385 random_(0x89674523), |
| 338 stddev_jitter_us_(0), | 386 stddev_jitter_us_(0), |
| 339 last_send_time_us_(0) { | 387 last_send_time_us_(0) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 int64_t t2 = (*it)->send_time_us(); | 445 int64_t t2 = (*it)->send_time_us(); |
| 398 std::swap(*last_it, *it); | 446 std::swap(*last_it, *it); |
| 399 (*last_it)->set_send_time_us(t1); | 447 (*last_it)->set_send_time_us(t1); |
| 400 (*it)->set_send_time_us(t2); | 448 (*it)->set_send_time_us(t2); |
| 401 } | 449 } |
| 402 last_it = it; | 450 last_it = it; |
| 403 } | 451 } |
| 404 } | 452 } |
| 405 } | 453 } |
| 406 | 454 |
| 455 const uint32_t kDefaultKbps = 1200; | |
| 456 | |
| 407 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, int flow_id) | 457 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, int flow_id) |
| 408 : PacketProcessor(listener, flow_id, kRegular), | 458 : PacketProcessor(listener, flow_id, kRegular), |
| 409 kbps_(1200), | 459 capacity_kbps_(kDefaultKbps), |
| 410 last_send_time_us_(0), | 460 last_send_time_us_(0), |
| 411 delay_cap_helper_(new DelayCapHelper()) { | 461 delay_cap_helper_(new DelayCapHelper()) { |
| 412 } | 462 } |
| 413 | 463 |
| 414 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, | 464 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, |
| 415 const FlowIds& flow_ids) | 465 const FlowIds& flow_ids) |
| 416 : PacketProcessor(listener, flow_ids, kRegular), | 466 : PacketProcessor(listener, flow_ids, kRegular), |
| 417 kbps_(1200), | 467 capacity_kbps_(kDefaultKbps), |
| 418 last_send_time_us_(0), | 468 last_send_time_us_(0), |
| 419 delay_cap_helper_(new DelayCapHelper()) { | 469 delay_cap_helper_(new DelayCapHelper()) { |
| 420 } | 470 } |
| 421 | 471 |
| 422 ChokeFilter::~ChokeFilter() {} | 472 ChokeFilter::~ChokeFilter() {} |
| 423 | 473 |
| 424 void ChokeFilter::SetCapacity(uint32_t kbps) { | 474 void ChokeFilter::set_capacity_kbps(uint32_t kbps) { |
| 425 BWE_TEST_LOGGING_ENABLE(false); | 475 BWE_TEST_LOGGING_ENABLE(false); |
| 426 BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps); | 476 BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps); |
| 427 kbps_ = kbps; | 477 capacity_kbps_ = kbps; |
| 478 } | |
| 479 | |
| 480 uint32_t ChokeFilter::capacity_kbps() { | |
| 481 return capacity_kbps_; | |
| 428 } | 482 } |
| 429 | 483 |
| 430 void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { | 484 void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { |
| 431 assert(in_out); | 485 assert(in_out); |
| 432 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { | 486 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { |
| 433 int64_t earliest_send_time_us = | 487 int64_t earliest_send_time_us = |
| 434 std::max(last_send_time_us_, (*it)->send_time_us()); | 488 std::max(last_send_time_us_, (*it)->send_time_us()); |
| 489 | |
| 435 int64_t new_send_time_us = | 490 int64_t new_send_time_us = |
| 436 earliest_send_time_us + | 491 earliest_send_time_us + |
| 437 ((*it)->payload_size() * 8 * 1000 + kbps_ / 2) / kbps_; | 492 ((*it)->payload_size() * 8 * 1000 + capacity_kbps_ / 2) / |
| 493 capacity_kbps_; | |
| 494 | |
| 438 if (delay_cap_helper_->ShouldSendPacket(new_send_time_us, | 495 if (delay_cap_helper_->ShouldSendPacket(new_send_time_us, |
| 439 (*it)->send_time_us())) { | 496 (*it)->send_time_us())) { |
| 440 (*it)->set_send_time_us(new_send_time_us); | 497 (*it)->set_send_time_us(new_send_time_us); |
| 441 last_send_time_us_ = new_send_time_us; | 498 last_send_time_us_ = new_send_time_us; |
| 442 ++it; | 499 ++it; |
| 443 } else { | 500 } else { |
| 444 delete *it; | 501 delete *it; |
| 445 it = in_out->erase(it); | 502 it = in_out->erase(it); |
| 446 } | 503 } |
| 447 } | 504 } |
| 448 } | 505 } |
| 449 | 506 |
| 450 void ChokeFilter::SetMaxDelay(int max_delay_ms) { | 507 void ChokeFilter::set_max_delay_ms(int64_t max_delay_ms) { |
| 451 delay_cap_helper_->SetMaxDelay(max_delay_ms); | 508 delay_cap_helper_->set_max_delay_ms(max_delay_ms); |
| 452 } | 509 } |
| 453 | 510 |
| 454 Stats<double> ChokeFilter::GetDelayStats() const { | 511 Stats<double> ChokeFilter::GetDelayStats() const { |
| 455 return delay_cap_helper_->delay_stats(); | 512 return delay_cap_helper_->delay_stats(); |
| 456 } | 513 } |
| 457 | 514 |
| 458 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( | 515 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( |
| 459 PacketProcessorListener* listener, | 516 PacketProcessorListener* listener, |
| 460 int flow_id) | 517 int flow_id) |
| 461 : PacketProcessor(listener, flow_id, kRegular), | 518 : PacketProcessor(listener, flow_id, kRegular), |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 558 if (local_time_us_ >= (*it)->send_time_us()) { | 615 if (local_time_us_ >= (*it)->send_time_us()) { |
| 559 (*it)->set_send_time_us(local_time_us_); | 616 (*it)->set_send_time_us(local_time_us_); |
| 560 ProceedToNextSlot(); | 617 ProceedToNextSlot(); |
| 561 } | 618 } |
| 562 ++it; | 619 ++it; |
| 563 } | 620 } |
| 564 packets_per_second_stats_.Push(rate_counter_->packets_per_second()); | 621 packets_per_second_stats_.Push(rate_counter_->packets_per_second()); |
| 565 kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0); | 622 kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0); |
| 566 } | 623 } |
| 567 | 624 |
| 568 void TraceBasedDeliveryFilter::SetMaxDelay(int max_delay_ms) { | 625 void TraceBasedDeliveryFilter::set_max_delay_ms(int64_t max_delay_ms) { |
| 569 delay_cap_helper_->SetMaxDelay(max_delay_ms); | 626 delay_cap_helper_->set_max_delay_ms(max_delay_ms); |
| 570 } | 627 } |
| 571 | 628 |
| 572 Stats<double> TraceBasedDeliveryFilter::GetDelayStats() const { | 629 Stats<double> TraceBasedDeliveryFilter::GetDelayStats() const { |
| 573 return delay_cap_helper_->delay_stats(); | 630 return delay_cap_helper_->delay_stats(); |
| 574 } | 631 } |
| 575 | 632 |
| 576 Stats<double> TraceBasedDeliveryFilter::GetBitrateStats() const { | 633 Stats<double> TraceBasedDeliveryFilter::GetBitrateStats() const { |
| 577 return kbps_stats_; | 634 return kbps_stats_; |
| 578 } | 635 } |
| 579 | 636 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 600 uint32_t ssrc, | 657 uint32_t ssrc, |
| 601 int64_t first_frame_offset_ms) | 658 int64_t first_frame_offset_ms) |
| 602 : kMaxPayloadSizeBytes(1200), | 659 : kMaxPayloadSizeBytes(1200), |
| 603 kTimestampBase(0xff80ff00ul), | 660 kTimestampBase(0xff80ff00ul), |
| 604 frame_period_ms_(1000.0 / fps), | 661 frame_period_ms_(1000.0 / fps), |
| 605 bits_per_second_(1000 * kbps), | 662 bits_per_second_(1000 * kbps), |
| 606 frame_size_bytes_(bits_per_second_ / 8 / fps), | 663 frame_size_bytes_(bits_per_second_ / 8 / fps), |
| 607 flow_id_(flow_id), | 664 flow_id_(flow_id), |
| 608 next_frame_ms_(first_frame_offset_ms), | 665 next_frame_ms_(first_frame_offset_ms), |
| 609 now_ms_(0), | 666 now_ms_(0), |
| 610 prototype_header_() { | 667 prototype_header_(), |
| 668 start_plotting_ms_(first_frame_offset_ms) { | |
| 611 memset(&prototype_header_, 0, sizeof(prototype_header_)); | 669 memset(&prototype_header_, 0, sizeof(prototype_header_)); |
| 612 prototype_header_.ssrc = ssrc; | 670 prototype_header_.ssrc = ssrc; |
| 613 prototype_header_.sequenceNumber = 0xf000u; | 671 prototype_header_.sequenceNumber = 0xf000u; |
| 614 } | 672 } |
| 615 | 673 |
| 616 uint32_t VideoSource::NextFrameSize() { | 674 uint32_t VideoSource::NextFrameSize() { |
| 617 return frame_size_bytes_; | 675 return frame_size_bytes_; |
| 618 } | 676 } |
| 619 | 677 |
| 678 int64_t VideoSource::GetTimeUntilNextFrameMs() const { | |
| 679 return next_frame_ms_ + next_frame_rand_ms_ - now_ms_; | |
|
stefan-webrtc
2015/07/15 11:31:41
next_frame_rand_ms_ must be initialized.
magalhaesc
2015/07/15 11:41:59
Done.
| |
| 680 } | |
| 681 | |
| 620 uint32_t VideoSource::NextPacketSize(uint32_t frame_size, | 682 uint32_t VideoSource::NextPacketSize(uint32_t frame_size, |
| 621 uint32_t remaining_payload) { | 683 uint32_t remaining_payload) { |
| 622 return std::min(kMaxPayloadSizeBytes, remaining_payload); | 684 return std::min(kMaxPayloadSizeBytes, remaining_payload); |
| 623 } | 685 } |
| 624 | 686 |
| 625 void VideoSource::RunFor(int64_t time_ms, Packets* in_out) { | 687 void VideoSource::RunFor(int64_t time_ms, Packets* in_out) { |
| 626 assert(in_out); | 688 assert(in_out); |
| 627 std::stringstream ss; | 689 |
| 628 ss << "SendEstimate_" << flow_id_ << "#1"; | |
| 629 BWE_TEST_LOGGING_PLOT(0, ss.str(), now_ms_, bits_per_second_ / 1000); | |
| 630 now_ms_ += time_ms; | 690 now_ms_ += time_ms; |
| 631 Packets new_packets; | 691 Packets new_packets; |
| 692 | |
| 632 while (now_ms_ >= next_frame_ms_) { | 693 while (now_ms_ >= next_frame_ms_) { |
| 633 prototype_header_.timestamp = kTimestampBase + | 694 const int64_t kRandAmplitude = 2; |
| 634 static_cast<uint32_t>(next_frame_ms_ * 90.0); | 695 // A variance picked uniformly from {-1, 0, 1} ms is added to the frame |
| 696 // timestamp. | |
| 697 next_frame_rand_ms_ = | |
| 698 kRandAmplitude * static_cast<float>(rand()) / RAND_MAX - | |
| 699 kRandAmplitude / 2; | |
| 700 | |
| 701 // Ensure frame will not have a negative timestamp. | |
| 702 int64_t next_frame_ms = | |
| 703 std::max(next_frame_ms_ + next_frame_rand_ms_, static_cast<int64_t>(0)); | |
|
stefan-webrtc
2015/07/15 11:28:20
nit
You can also do
std::max<int64_t>()
magalhaesc
2015/07/15 11:41:59
Done.
| |
| 704 | |
| 705 prototype_header_.timestamp = | |
| 706 kTimestampBase + static_cast<uint32_t>(next_frame_ms * 90.0); | |
| 635 prototype_header_.extension.transmissionTimeOffset = 0; | 707 prototype_header_.extension.transmissionTimeOffset = 0; |
| 636 | 708 |
| 637 // Generate new packets for this frame, all with the same timestamp, | 709 // Generate new packets for this frame, all with the same timestamp, |
| 638 // but the payload size is capped, so if the whole frame doesn't fit in | 710 // but the payload size is capped, so if the whole frame doesn't fit in |
| 639 // one packet, we will see a number of equally sized packets followed by | 711 // one packet, we will see a number of equally sized packets followed by |
| 640 // one smaller at the tail. | 712 // one smaller at the tail. |
| 641 int64_t send_time_us = next_frame_ms_ * 1000.0; | 713 |
| 714 int64_t send_time_us = next_frame_ms * 1000.0; | |
| 715 | |
| 642 uint32_t frame_size = NextFrameSize(); | 716 uint32_t frame_size = NextFrameSize(); |
| 643 uint32_t payload_size = frame_size; | 717 uint32_t payload_size = frame_size; |
| 644 | 718 |
| 645 while (payload_size > 0) { | 719 while (payload_size > 0) { |
| 646 ++prototype_header_.sequenceNumber; | 720 ++prototype_header_.sequenceNumber; |
| 647 uint32_t size = NextPacketSize(frame_size, payload_size); | 721 uint32_t size = NextPacketSize(frame_size, payload_size); |
| 648 MediaPacket* new_packet = | 722 MediaPacket* new_packet = |
| 649 new MediaPacket(flow_id_, send_time_us, size, prototype_header_); | 723 new MediaPacket(flow_id_, send_time_us, size, prototype_header_); |
| 650 new_packets.push_back(new_packet); | 724 new_packets.push_back(new_packet); |
| 651 new_packet->SetAbsSendTimeMs(next_frame_ms_); | 725 new_packet->SetAbsSendTimeMs(next_frame_ms); |
| 652 new_packet->set_sender_timestamp_us(send_time_us); | 726 new_packet->set_sender_timestamp_us(send_time_us); |
| 653 payload_size -= size; | 727 payload_size -= size; |
| 654 } | 728 } |
| 655 | 729 |
| 656 next_frame_ms_ += frame_period_ms_; | 730 next_frame_ms_ += frame_period_ms_; |
| 657 } | 731 } |
| 732 | |
| 658 in_out->merge(new_packets, DereferencingComparator<Packet>); | 733 in_out->merge(new_packets, DereferencingComparator<Packet>); |
| 659 } | 734 } |
| 660 | 735 |
| 661 AdaptiveVideoSource::AdaptiveVideoSource(int flow_id, | 736 AdaptiveVideoSource::AdaptiveVideoSource(int flow_id, |
| 662 float fps, | 737 float fps, |
| 663 uint32_t kbps, | 738 uint32_t kbps, |
| 664 uint32_t ssrc, | 739 uint32_t ssrc, |
| 665 int64_t first_frame_offset_ms) | 740 int64_t first_frame_offset_ms) |
| 666 : VideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms) { | 741 : VideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms) { |
| 667 } | 742 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 714 uint32_t PeriodicKeyFrameSource::NextPacketSize(uint32_t frame_size, | 789 uint32_t PeriodicKeyFrameSource::NextPacketSize(uint32_t frame_size, |
| 715 uint32_t remaining_payload) { | 790 uint32_t remaining_payload) { |
| 716 uint32_t fragments = | 791 uint32_t fragments = |
| 717 (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes; | 792 (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes; |
| 718 uint32_t avg_size = (frame_size + fragments - 1) / fragments; | 793 uint32_t avg_size = (frame_size + fragments - 1) / fragments; |
| 719 return std::min(avg_size, remaining_payload); | 794 return std::min(avg_size, remaining_payload); |
| 720 } | 795 } |
| 721 } // namespace bwe | 796 } // namespace bwe |
| 722 } // namespace testing | 797 } // namespace testing |
| 723 } // namespace webrtc | 798 } // namespace webrtc |
| OLD | NEW |