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 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h" 12 13 #include <stdio.h> 14 15 #include <sstream> 16 17 namespace webrtc { 18 namespace testing { 19 namespace bwe { 20 21 class DelayCapHelper { 22 public: 23 // Max delay = 0 stands for +infinite. 24 DelayCapHelper() : max_delay_us_(0), delay_stats_() {} 25 26 void set_max_delay_ms(int64_t max_delay_ms) { 27 BWE_TEST_LOGGING_ENABLE(false); 28 BWE_TEST_LOGGING_LOG1("Max Delay", "%d ms", static_cast<int>(max_delay_ms)); 29 assert(max_delay_ms >= 0); 30 max_delay_us_ = max_delay_ms * 1000; 31 } 32 33 bool ShouldSendPacket(int64_t send_time_us, int64_t arrival_time_us) { 34 int64_t packet_delay_us = send_time_us - arrival_time_us; 35 delay_stats_.Push((std::min(packet_delay_us, max_delay_us_) + 500) / 1000); 36 return (max_delay_us_ == 0 || max_delay_us_ >= packet_delay_us); 37 } 38 39 const Stats<double>& delay_stats() const { 40 return delay_stats_; 41 } 42 43 private: 44 int64_t max_delay_us_; 45 Stats<double> delay_stats_; 46 47 RTC_DISALLOW_COPY_AND_ASSIGN(DelayCapHelper); 48 }; 49 50 const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids) { 51 FlowIds flow_ids(&flow_ids_array[0], flow_ids_array + num_flow_ids); 52 return flow_ids; 53 } 54 55 const FlowIds CreateFlowIdRange(int initial_value, int last_value) { 56 int size = last_value - initial_value + 1; 57 assert(size > 0); 58 int* flow_ids_array = new int[size]; 59 for (int i = initial_value; i <= last_value; ++i) { 60 flow_ids_array[i - initial_value] = i; 61 } 62 return CreateFlowIds(flow_ids_array, size); 63 } 64 65 void RateCounter::UpdateRates(int64_t send_time_us, uint32_t payload_size) { 66 ++recently_received_packets_; 67 recently_received_bytes_ += payload_size; 68 last_accumulated_us_ = send_time_us; 69 window_.push_back(std::make_pair(send_time_us, payload_size)); 70 while (!window_.empty()) { 71 const TimeSizePair& packet = window_.front(); 72 if (packet.first > (last_accumulated_us_ - window_size_us_)) { 73 break; 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(); 80 } 81 } 82 83 uint32_t RateCounter::bits_per_second() const { 84 return (8 * recently_received_bytes_) / BitrateWindowS(); 85 } 86 87 uint32_t RateCounter::packets_per_second() const { 88 return recently_received_packets_ / BitrateWindowS(); 89 } 90 91 double RateCounter::BitrateWindowS() const { 92 return static_cast<double>(window_size_us_) / (1000 * 1000); 93 } 94 95 Packet::Packet() 96 : flow_id_(0), 97 creation_time_us_(-1), 98 send_time_us_(-1), 99 sender_timestamp_us_(-1), 100 payload_size_(0), 101 paced_(false) { 102 } 103 104 Packet::Packet(int flow_id, int64_t send_time_us, size_t payload_size) 105 : flow_id_(flow_id), 106 creation_time_us_(send_time_us), 107 send_time_us_(send_time_us), 108 sender_timestamp_us_(send_time_us), 109 payload_size_(payload_size), 110 paced_(false) { 111 } 112 113 Packet::~Packet() { 114 } 115 116 bool Packet::operator<(const Packet& rhs) const { 117 return send_time_us_ < rhs.send_time_us_; 118 } 119 120 void Packet::set_send_time_us(int64_t send_time_us) { 121 assert(send_time_us >= 0); 122 send_time_us_ = send_time_us; 123 } 124 125 MediaPacket::MediaPacket() { 126 memset(&header_, 0, sizeof(header_)); 127 } 128 129 MediaPacket::MediaPacket(int flow_id, 130 int64_t send_time_us, 131 size_t payload_size, 132 uint16_t sequence_number) 133 : Packet(flow_id, send_time_us, payload_size) { 134 header_ = RTPHeader(); 135 header_.sequenceNumber = sequence_number; 136 } 137 138 MediaPacket::MediaPacket(int flow_id, 139 int64_t send_time_us, 140 size_t payload_size, 141 const RTPHeader& header) 142 : Packet(flow_id, send_time_us, payload_size), header_(header) { 143 } 144 145 MediaPacket::MediaPacket(int64_t send_time_us, uint16_t sequence_number) 146 : Packet(0, send_time_us, 0) { 147 header_ = RTPHeader(); 148 header_.sequenceNumber = sequence_number; 149 } 150 151 void MediaPacket::SetAbsSendTimeMs(int64_t abs_send_time_ms) { 152 header_.extension.hasAbsoluteSendTime = true; 153 header_.extension.absoluteSendTime = ((static_cast<int64_t>(abs_send_time_ms * 154 (1 << 18)) + 500) / 1000) & 0x00fffffful; 155 } 156 157 RembFeedback::RembFeedback(int flow_id, 158 int64_t send_time_us, 159 int64_t last_send_time_ms, 160 uint32_t estimated_bps, 161 RTCPReportBlock report_block) 162 : FeedbackPacket(flow_id, send_time_us, last_send_time_ms), 163 estimated_bps_(estimated_bps), 164 report_block_(report_block) { 165 } 166 167 SendSideBweFeedback::SendSideBweFeedback( 168 int flow_id, 169 int64_t send_time_us, 170 int64_t last_send_time_ms, 171 const std::vector<PacketInfo>& packet_feedback_vector) 172 : FeedbackPacket(flow_id, send_time_us, last_send_time_ms), 173 packet_feedback_vector_(packet_feedback_vector) { 174 } 175 176 bool IsTimeSorted(const Packets& packets) { 177 PacketsConstIt last_it = packets.begin(); 178 for (PacketsConstIt it = last_it; it != packets.end(); ++it) { 179 if (it != last_it && **it < **last_it) { 180 return false; 181 } 182 last_it = it; 183 } 184 return true; 185 } 186 187 PacketProcessor::PacketProcessor(PacketProcessorListener* listener, 188 int flow_id, 189 ProcessorType type) 190 : listener_(listener), flow_ids_(&flow_id, &flow_id + 1) { 191 if (listener_) { 192 listener_->AddPacketProcessor(this, type); 193 } 194 } 195 196 PacketProcessor::PacketProcessor(PacketProcessorListener* listener, 197 const FlowIds& flow_ids, 198 ProcessorType type) 199 : listener_(listener), flow_ids_(flow_ids) { 200 if (listener_) { 201 listener_->AddPacketProcessor(this, type); 202 } 203 } 204 205 PacketProcessor::~PacketProcessor() { 206 if (listener_) { 207 listener_->RemovePacketProcessor(this); 208 } 209 } 210 211 uint32_t PacketProcessor::packets_per_second() const { 212 return rate_counter_.packets_per_second(); 213 } 214 215 uint32_t PacketProcessor::bits_per_second() const { 216 return rate_counter_.bits_per_second(); 217 } 218 219 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, 220 int flow_id, 221 const char* name, 222 const std::string& plot_name) 223 : PacketProcessor(listener, flow_id, kRegular), 224 packets_per_second_stats_(), 225 kbps_stats_(), 226 start_plotting_time_ms_(0), 227 plot_name_(plot_name) { 228 std::stringstream ss; 229 ss << name << "_" << flow_id; 230 name_ = ss.str(); 231 } 232 233 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, 234 const FlowIds& flow_ids, 235 const char* name, 236 const std::string& plot_name) 237 : PacketProcessor(listener, flow_ids, kRegular), 238 packets_per_second_stats_(), 239 kbps_stats_(), 240 start_plotting_time_ms_(0), 241 plot_name_(plot_name) { 242 std::stringstream ss; 243 ss << name; 244 char delimiter = '_'; 245 for (int flow_id : flow_ids) { 246 ss << delimiter << flow_id; 247 delimiter = ','; 248 } 249 name_ = ss.str(); 250 } 251 252 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, 253 const FlowIds& flow_ids, 254 const char* name, 255 int64_t start_plotting_time_ms, 256 const std::string& plot_name) 257 : RateCounterFilter(listener, flow_ids, name, plot_name) { 258 start_plotting_time_ms_ = start_plotting_time_ms; 259 } 260 261 RateCounterFilter::~RateCounterFilter() { 262 LogStats(); 263 } 264 265 266 void RateCounterFilter::LogStats() { 267 BWE_TEST_LOGGING_CONTEXT("RateCounterFilter"); 268 packets_per_second_stats_.Log("pps"); 269 kbps_stats_.Log("kbps"); 270 } 271 272 Stats<double> RateCounterFilter::GetBitrateStats() const { 273 return kbps_stats_; 274 } 275 276 void RateCounterFilter::Plot(int64_t timestamp_ms) { 277 uint32_t plot_kbps = 0; 278 if (timestamp_ms >= start_plotting_time_ms_) { 279 plot_kbps = rate_counter_.bits_per_second() / 1000.0; 280 } 281 BWE_TEST_LOGGING_CONTEXT(name_.c_str()); 282 if (plot_name_.empty()) { 283 BWE_TEST_LOGGING_PLOT(0, "Throughput_kbps#1", timestamp_ms, plot_kbps); 284 } else { 285 BWE_TEST_LOGGING_PLOT_WITH_NAME(0, "Throughput_kbps#1", timestamp_ms, 286 plot_kbps, plot_name_); 287 } 288 289 RTC_UNUSED(plot_kbps); 290 } 291 292 void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { 293 assert(in_out); 294 for (const Packet* packet : *in_out) { 295 rate_counter_.UpdateRates(packet->send_time_us(), 296 static_cast<int>(packet->payload_size())); 297 } 298 packets_per_second_stats_.Push(rate_counter_.packets_per_second()); 299 kbps_stats_.Push(rate_counter_.bits_per_second() / 1000.0); 300 } 301 302 LossFilter::LossFilter(PacketProcessorListener* listener, int flow_id) 303 : PacketProcessor(listener, flow_id, kRegular), 304 random_(0x12345678), 305 loss_fraction_(0.0f) { 306 } 307 308 LossFilter::LossFilter(PacketProcessorListener* listener, 309 const FlowIds& flow_ids) 310 : PacketProcessor(listener, flow_ids, kRegular), 311 random_(0x12345678), 312 loss_fraction_(0.0f) { 313 } 314 315 void LossFilter::SetLoss(float loss_percent) { 316 BWE_TEST_LOGGING_ENABLE(false); 317 BWE_TEST_LOGGING_LOG1("Loss", "%f%%", loss_percent); 318 assert(loss_percent >= 0.0f); 319 assert(loss_percent <= 100.0f); 320 loss_fraction_ = loss_percent * 0.01f; 321 } 322 323 void LossFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { 324 assert(in_out); 325 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { 326 if (random_.Rand<float>() < loss_fraction_) { 327 delete *it; 328 it = in_out->erase(it); 329 } else { 330 ++it; 331 } 332 } 333 } 334 335 const int64_t kDefaultOneWayDelayUs = 0; 336 337 DelayFilter::DelayFilter(PacketProcessorListener* listener, int flow_id) 338 : PacketProcessor(listener, flow_id, kRegular), 339 one_way_delay_us_(kDefaultOneWayDelayUs), 340 last_send_time_us_(0) { 341 } 342 343 DelayFilter::DelayFilter(PacketProcessorListener* listener, 344 const FlowIds& flow_ids) 345 : PacketProcessor(listener, flow_ids, kRegular), 346 one_way_delay_us_(kDefaultOneWayDelayUs), 347 last_send_time_us_(0) { 348 } 349 350 void DelayFilter::SetOneWayDelayMs(int64_t one_way_delay_ms) { 351 BWE_TEST_LOGGING_ENABLE(false); 352 BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast<int>(one_way_delay_ms)); 353 assert(one_way_delay_ms >= 0); 354 one_way_delay_us_ = one_way_delay_ms * 1000; 355 } 356 357 void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { 358 assert(in_out); 359 for (Packet* packet : *in_out) { 360 int64_t new_send_time_us = packet->send_time_us() + one_way_delay_us_; 361 last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us); 362 packet->set_send_time_us(last_send_time_us_); 363 } 364 } 365 366 JitterFilter::JitterFilter(PacketProcessorListener* listener, int flow_id) 367 : PacketProcessor(listener, flow_id, kRegular), 368 random_(0x89674523), 369 stddev_jitter_us_(0), 370 last_send_time_us_(0), 371 reordering_(false) { 372 } 373 374 JitterFilter::JitterFilter(PacketProcessorListener* listener, 375 const FlowIds& flow_ids) 376 : PacketProcessor(listener, flow_ids, kRegular), 377 random_(0x89674523), 378 stddev_jitter_us_(0), 379 last_send_time_us_(0), 380 reordering_(false) { 381 } 382 383 const int kN = 3; // Truncated N sigma gaussian. 384 385 void JitterFilter::SetMaxJitter(int64_t max_jitter_ms) { 386 BWE_TEST_LOGGING_ENABLE(false); 387 BWE_TEST_LOGGING_LOG1("Max Jitter", "%d ms", static_cast<int>(max_jitter_ms)); 388 assert(max_jitter_ms >= 0); 389 // Truncated gaussian, Max jitter = kN*sigma. 390 stddev_jitter_us_ = (max_jitter_ms * 1000 + kN / 2) / kN; 391 } 392 393 namespace { 394 inline int64_t TruncatedNSigmaGaussian(Random* const random, 395 int64_t mean, 396 int64_t std_dev) { 397 int64_t gaussian_random = random->Gaussian(mean, std_dev); 398 return std::max(std::min(gaussian_random, kN * std_dev), -kN * std_dev); 399 } 400 } 401 402 void JitterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { 403 assert(in_out); 404 for (Packet* packet : *in_out) { 405 int64_t jitter_us = 406 std::abs(TruncatedNSigmaGaussian(&random_, 0, stddev_jitter_us_)); 407 int64_t new_send_time_us = packet->send_time_us() + jitter_us; 408 409 if (!reordering_) { 410 new_send_time_us = std::max(last_send_time_us_, new_send_time_us); 411 } 412 413 // Receiver timestamp cannot be lower than sender timestamp. 414 assert(new_send_time_us >= packet->sender_timestamp_us()); 415 416 packet->set_send_time_us(new_send_time_us); 417 last_send_time_us_ = new_send_time_us; 418 } 419 } 420 421 // Computes the expected value for a right sided (abs) truncated gaussian. 422 // Does not take into account possible reoerdering updates. 423 int64_t JitterFilter::MeanUs() { 424 const double kPi = 3.1415926535897932; 425 double max_jitter_us = static_cast<double>(kN * stddev_jitter_us_); 426 double right_sided_mean_us = 427 static_cast<double>(stddev_jitter_us_) / sqrt(kPi / 2.0); 428 double truncated_mean_us = 429 right_sided_mean_us * 430 (1.0 - exp(-pow(static_cast<double>(kN), 2.0) / 2.0)) + 431 max_jitter_us * erfc(static_cast<double>(kN)); 432 return static_cast<int64_t>(truncated_mean_us + 0.5); 433 } 434 435 ReorderFilter::ReorderFilter(PacketProcessorListener* listener, int flow_id) 436 : PacketProcessor(listener, flow_id, kRegular), 437 random_(0x27452389), 438 reorder_fraction_(0.0f) { 439 } 440 441 ReorderFilter::ReorderFilter(PacketProcessorListener* listener, 442 const FlowIds& flow_ids) 443 : PacketProcessor(listener, flow_ids, kRegular), 444 random_(0x27452389), 445 reorder_fraction_(0.0f) { 446 } 447 448 void ReorderFilter::SetReorder(float reorder_percent) { 449 BWE_TEST_LOGGING_ENABLE(false); 450 BWE_TEST_LOGGING_LOG1("Reordering", "%f%%", reorder_percent); 451 assert(reorder_percent >= 0.0f); 452 assert(reorder_percent <= 100.0f); 453 reorder_fraction_ = reorder_percent * 0.01f; 454 } 455 456 void ReorderFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { 457 assert(in_out); 458 if (in_out->size() >= 2) { 459 PacketsIt last_it = in_out->begin(); 460 PacketsIt it = last_it; 461 while (++it != in_out->end()) { 462 if (random_.Rand<float>() < reorder_fraction_) { 463 int64_t t1 = (*last_it)->send_time_us(); 464 int64_t t2 = (*it)->send_time_us(); 465 std::swap(*last_it, *it); 466 (*last_it)->set_send_time_us(t1); 467 (*it)->set_send_time_us(t2); 468 } 469 last_it = it; 470 } 471 } 472 } 473 474 const uint32_t kDefaultKbps = 1200; 475 476 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, int flow_id) 477 : PacketProcessor(listener, flow_id, kRegular), 478 capacity_kbps_(kDefaultKbps), 479 last_send_time_us_(0), 480 delay_cap_helper_(new DelayCapHelper()) { 481 } 482 483 ChokeFilter::ChokeFilter(PacketProcessorListener* listener, 484 const FlowIds& flow_ids) 485 : PacketProcessor(listener, flow_ids, kRegular), 486 capacity_kbps_(kDefaultKbps), 487 last_send_time_us_(0), 488 delay_cap_helper_(new DelayCapHelper()) { 489 } 490 491 ChokeFilter::~ChokeFilter() {} 492 493 void ChokeFilter::set_capacity_kbps(uint32_t kbps) { 494 BWE_TEST_LOGGING_ENABLE(false); 495 BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps); 496 capacity_kbps_ = kbps; 497 } 498 499 uint32_t ChokeFilter::capacity_kbps() { 500 return capacity_kbps_; 501 } 502 503 void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { 504 assert(in_out); 505 for (PacketsIt it = in_out->begin(); it != in_out->end(); ) { 506 int64_t earliest_send_time_us = 507 std::max(last_send_time_us_, (*it)->send_time_us()); 508 509 int64_t new_send_time_us = 510 earliest_send_time_us + 511 ((*it)->payload_size() * 8 * 1000 + capacity_kbps_ / 2) / 512 capacity_kbps_; 513 514 if (delay_cap_helper_->ShouldSendPacket(new_send_time_us, 515 (*it)->send_time_us())) { 516 (*it)->set_send_time_us(new_send_time_us); 517 last_send_time_us_ = new_send_time_us; 518 ++it; 519 } else { 520 delete *it; 521 it = in_out->erase(it); 522 } 523 } 524 } 525 526 void ChokeFilter::set_max_delay_ms(int64_t max_delay_ms) { 527 delay_cap_helper_->set_max_delay_ms(max_delay_ms); 528 } 529 530 Stats<double> ChokeFilter::GetDelayStats() const { 531 return delay_cap_helper_->delay_stats(); 532 } 533 534 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( 535 PacketProcessorListener* listener, 536 int flow_id) 537 : PacketProcessor(listener, flow_id, kRegular), 538 current_offset_us_(0), 539 delivery_times_us_(), 540 next_delivery_it_(), 541 local_time_us_(-1), 542 rate_counter_(new RateCounter), 543 name_(""), 544 delay_cap_helper_(new DelayCapHelper()), 545 packets_per_second_stats_(), 546 kbps_stats_() { 547 } 548 549 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( 550 PacketProcessorListener* listener, 551 const FlowIds& flow_ids) 552 : PacketProcessor(listener, flow_ids, kRegular), 553 current_offset_us_(0), 554 delivery_times_us_(), 555 next_delivery_it_(), 556 local_time_us_(-1), 557 rate_counter_(new RateCounter), 558 name_(""), 559 delay_cap_helper_(new DelayCapHelper()), 560 packets_per_second_stats_(), 561 kbps_stats_() { 562 } 563 564 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( 565 PacketProcessorListener* listener, 566 int flow_id, 567 const char* name) 568 : PacketProcessor(listener, flow_id, kRegular), 569 current_offset_us_(0), 570 delivery_times_us_(), 571 next_delivery_it_(), 572 local_time_us_(-1), 573 rate_counter_(new RateCounter), 574 name_(name), 575 delay_cap_helper_(new DelayCapHelper()), 576 packets_per_second_stats_(), 577 kbps_stats_() { 578 } 579 580 TraceBasedDeliveryFilter::~TraceBasedDeliveryFilter() { 581 } 582 583 bool TraceBasedDeliveryFilter::Init(const std::string& filename) { 584 FILE* trace_file = fopen(filename.c_str(), "r"); 585 if (!trace_file) { 586 return false; 587 } 588 int64_t first_timestamp = -1; 589 while (!feof(trace_file)) { 590 const size_t kMaxLineLength = 100; 591 char line[kMaxLineLength]; 592 if (fgets(line, kMaxLineLength, trace_file)) { 593 std::string line_string(line); 594 std::istringstream buffer(line_string); 595 int64_t timestamp; 596 buffer >> timestamp; 597 timestamp /= 1000; // Convert to microseconds. 598 if (first_timestamp == -1) 599 first_timestamp = timestamp; 600 assert(delivery_times_us_.empty() || 601 timestamp - first_timestamp - delivery_times_us_.back() >= 0); 602 delivery_times_us_.push_back(timestamp - first_timestamp); 603 } 604 } 605 assert(!delivery_times_us_.empty()); 606 next_delivery_it_ = delivery_times_us_.begin(); 607 fclose(trace_file); 608 return true; 609 } 610 611 void TraceBasedDeliveryFilter::Plot(int64_t timestamp_ms) { 612 BWE_TEST_LOGGING_CONTEXT(name_.c_str()); 613 // This plots the max possible throughput of the trace-based delivery filter, 614 // which will be reached if a packet sent on every packet slot of the trace. 615 BWE_TEST_LOGGING_PLOT(0, "MaxThroughput_#1", timestamp_ms, 616 rate_counter_->bits_per_second() / 1000.0); 617 } 618 619 void TraceBasedDeliveryFilter::RunFor(int64_t time_ms, Packets* in_out) { 620 assert(in_out); 621 for (PacketsIt it = in_out->begin(); it != in_out->end();) { 622 while (local_time_us_ < (*it)->send_time_us()) { 623 ProceedToNextSlot(); 624 } 625 // Drop any packets that have been queued for too long. 626 while (!delay_cap_helper_->ShouldSendPacket(local_time_us_, 627 (*it)->send_time_us())) { 628 delete *it; 629 it = in_out->erase(it); 630 if (it == in_out->end()) { 631 return; 632 } 633 } 634 if (local_time_us_ >= (*it)->send_time_us()) { 635 (*it)->set_send_time_us(local_time_us_); 636 ProceedToNextSlot(); 637 } 638 ++it; 639 } 640 packets_per_second_stats_.Push(rate_counter_->packets_per_second()); 641 kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0); 642 } 643 644 void TraceBasedDeliveryFilter::set_max_delay_ms(int64_t max_delay_ms) { 645 delay_cap_helper_->set_max_delay_ms(max_delay_ms); 646 } 647 648 Stats<double> TraceBasedDeliveryFilter::GetDelayStats() const { 649 return delay_cap_helper_->delay_stats(); 650 } 651 652 Stats<double> TraceBasedDeliveryFilter::GetBitrateStats() const { 653 return kbps_stats_; 654 } 655 656 void TraceBasedDeliveryFilter::ProceedToNextSlot() { 657 if (*next_delivery_it_ <= local_time_us_) { 658 ++next_delivery_it_; 659 if (next_delivery_it_ == delivery_times_us_.end()) { 660 // When the trace wraps we allow two packets to be sent back-to-back. 661 for (int64_t& delivery_time_us : delivery_times_us_) { 662 delivery_time_us += local_time_us_ - current_offset_us_; 663 } 664 current_offset_us_ += local_time_us_ - current_offset_us_; 665 next_delivery_it_ = delivery_times_us_.begin(); 666 } 667 } 668 local_time_us_ = *next_delivery_it_; 669 const int kPayloadSize = 1200; 670 rate_counter_->UpdateRates(local_time_us_, kPayloadSize); 671 } 672 673 VideoSource::VideoSource(int flow_id, 674 float fps, 675 uint32_t kbps, 676 uint32_t ssrc, 677 int64_t first_frame_offset_ms) 678 : kMaxPayloadSizeBytes(1200), 679 kTimestampBase(0xff80ff00ul), 680 frame_period_ms_(1000.0 / fps), 681 bits_per_second_(1000 * kbps), 682 frame_size_bytes_(bits_per_second_ / 8 / fps), 683 random_(0x12345678), 684 flow_id_(flow_id), 685 next_frame_ms_(first_frame_offset_ms), 686 next_frame_rand_ms_(0), 687 now_ms_(0), 688 prototype_header_() { 689 memset(&prototype_header_, 0, sizeof(prototype_header_)); 690 prototype_header_.ssrc = ssrc; 691 prototype_header_.sequenceNumber = 0xf000u; 692 } 693 694 uint32_t VideoSource::NextFrameSize() { 695 return frame_size_bytes_; 696 } 697 698 int64_t VideoSource::GetTimeUntilNextFrameMs() const { 699 return next_frame_ms_ + next_frame_rand_ms_ - now_ms_; 700 } 701 702 uint32_t VideoSource::NextPacketSize(uint32_t frame_size, 703 uint32_t remaining_payload) { 704 return std::min(kMaxPayloadSizeBytes, remaining_payload); 705 } 706 707 void VideoSource::RunFor(int64_t time_ms, Packets* in_out) { 708 assert(in_out); 709 710 now_ms_ += time_ms; 711 Packets new_packets; 712 713 while (now_ms_ >= next_frame_ms_) { 714 const int64_t kRandAmplitude = 2; 715 // A variance picked uniformly from {-1, 0, 1} ms is added to the frame 716 // timestamp. 717 next_frame_rand_ms_ = kRandAmplitude * (random_.Rand<float>() - 0.5); 718 719 // Ensure frame will not have a negative timestamp. 720 int64_t next_frame_ms = 721 std::max<int64_t>(next_frame_ms_ + next_frame_rand_ms_, 0); 722 723 prototype_header_.timestamp = 724 kTimestampBase + static_cast<uint32_t>(next_frame_ms * 90.0); 725 prototype_header_.extension.transmissionTimeOffset = 0; 726 727 // Generate new packets for this frame, all with the same timestamp, 728 // but the payload size is capped, so if the whole frame doesn't fit in 729 // one packet, we will see a number of equally sized packets followed by 730 // one smaller at the tail. 731 732 int64_t send_time_us = next_frame_ms * 1000.0; 733 734 uint32_t frame_size = NextFrameSize(); 735 uint32_t payload_size = frame_size; 736 737 while (payload_size > 0) { 738 ++prototype_header_.sequenceNumber; 739 uint32_t size = NextPacketSize(frame_size, payload_size); 740 MediaPacket* new_packet = 741 new MediaPacket(flow_id_, send_time_us, size, prototype_header_); 742 new_packets.push_back(new_packet); 743 new_packet->SetAbsSendTimeMs(next_frame_ms); 744 new_packet->set_sender_timestamp_us(send_time_us); 745 payload_size -= size; 746 } 747 748 next_frame_ms_ += frame_period_ms_; 749 } 750 751 in_out->merge(new_packets, DereferencingComparator<Packet>); 752 } 753 754 AdaptiveVideoSource::AdaptiveVideoSource(int flow_id, 755 float fps, 756 uint32_t kbps, 757 uint32_t ssrc, 758 int64_t first_frame_offset_ms) 759 : VideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms) { 760 } 761 762 void AdaptiveVideoSource::SetBitrateBps(int bitrate_bps) { 763 bits_per_second_ = std::min(bitrate_bps, 2500000); 764 frame_size_bytes_ = (bits_per_second_ / 8 * frame_period_ms_ + 500) / 1000; 765 } 766 767 PeriodicKeyFrameSource::PeriodicKeyFrameSource(int flow_id, 768 float fps, 769 uint32_t kbps, 770 uint32_t ssrc, 771 int64_t first_frame_offset_ms, 772 int key_frame_interval) 773 : AdaptiveVideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms), 774 key_frame_interval_(key_frame_interval), 775 frame_counter_(0), 776 compensation_bytes_(0), 777 compensation_per_frame_(0) { 778 } 779 780 uint32_t PeriodicKeyFrameSource::NextFrameSize() { 781 uint32_t payload_size = frame_size_bytes_; 782 if (frame_counter_ == 0) { 783 payload_size = kMaxPayloadSizeBytes * 12; 784 compensation_bytes_ = 4 * frame_size_bytes_; 785 compensation_per_frame_ = compensation_bytes_ / 30; 786 } else if (key_frame_interval_ > 0 && 787 (frame_counter_ % key_frame_interval_ == 0)) { 788 payload_size *= 5; 789 compensation_bytes_ = payload_size - frame_size_bytes_; 790 compensation_per_frame_ = compensation_bytes_ / 30; 791 } else if (compensation_bytes_ > 0) { 792 if (compensation_per_frame_ > static_cast<int>(payload_size)) { 793 // Skip this frame. 794 compensation_bytes_ -= payload_size; 795 payload_size = 0; 796 } else { 797 payload_size -= compensation_per_frame_; 798 compensation_bytes_ -= compensation_per_frame_; 799 } 800 } 801 if (compensation_bytes_ < 0) 802 compensation_bytes_ = 0; 803 ++frame_counter_; 804 return payload_size; 805 } 806 807 uint32_t PeriodicKeyFrameSource::NextPacketSize(uint32_t frame_size, 808 uint32_t remaining_payload) { 809 uint32_t fragments = 810 (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes; 811 uint32_t avg_size = (frame_size + fragments - 1) / fragments; 812 return std::min(avg_size, remaining_payload); 813 } 814 } // namespace bwe 815 } // namespace testing 816 } // namespace webrtc 817