OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2017 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/bbr_paced_sender.h" |
| 12 |
| 13 #include <algorithm> |
| 14 #include <queue> |
| 15 #include <set> |
| 16 #include <vector> |
| 17 |
| 18 #include "webrtc/modules/pacing/paced_sender.h" |
| 19 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_win
dow.h" |
| 20 #include "webrtc/system_wrappers/include/clock.h" |
| 21 |
| 22 namespace webrtc { |
| 23 |
| 24 BbrPacedSender::BbrPacedSender(const Clock* clock, |
| 25 PacedSender::PacketSender* packet_sender, |
| 26 RtcEventLog* event_log) |
| 27 : clock_(clock), |
| 28 packet_sender_(packet_sender), |
| 29 estimated_bitrate_bps_(100000), |
| 30 min_send_bitrate_kbps_(0), |
| 31 pacing_bitrate_kbps_(0), |
| 32 time_last_update_us_(clock->TimeInMicroseconds()), |
| 33 time_last_update_ms_(clock->TimeInMilliseconds()), |
| 34 next_packet_send_time_(clock_->TimeInMilliseconds()), |
| 35 rounding_error_time_ms_(0.0f), |
| 36 packets_(), |
| 37 max_data_inflight_bytes_(10000), |
| 38 congestion_window_(new testing::bwe::CongestionWindow()) {} |
| 39 BbrPacedSender::~BbrPacedSender() {} |
| 40 |
| 41 void BbrPacedSender::SetEstimatedBitrateAndCongestionWindow( |
| 42 uint32_t bitrate_bps, |
| 43 bool in_probe_rtt, |
| 44 uint64_t congestion_window) { |
| 45 estimated_bitrate_bps_ = bitrate_bps; |
| 46 max_data_inflight_bytes_ = congestion_window; |
| 47 } |
| 48 |
| 49 void BbrPacedSender::SetMinBitrate(int min_send_bitrate_bps) { |
| 50 min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; |
| 51 pacing_bitrate_kbps_ = |
| 52 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000); |
| 53 } |
| 54 |
| 55 void BbrPacedSender::InsertPacket(RtpPacketSender::Priority priority, |
| 56 uint32_t ssrc, |
| 57 uint16_t sequence_number, |
| 58 int64_t capture_time_ms, |
| 59 size_t bytes, |
| 60 bool retransmission) { |
| 61 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 62 if (capture_time_ms < 0) |
| 63 capture_time_ms = now_ms; |
| 64 packets_.push_back(new Packet(priority, ssrc, sequence_number, |
| 65 capture_time_ms, now_ms, bytes, |
| 66 retransmission)); |
| 67 } |
| 68 |
| 69 int64_t BbrPacedSender::TimeUntilNextProcess() { |
| 70 // Once errors absolute value hits 1 millisecond, add compensating term to |
| 71 // the |next_packet_send_time_|, so that we can send packet earlier or later, |
| 72 // depending on the error. |
| 73 rounding_error_time_ms_ = std::min(rounding_error_time_ms_, 1.0f); |
| 74 if (rounding_error_time_ms_ < -0.9f) |
| 75 rounding_error_time_ms_ = -1.0f; |
| 76 int64_t result = |
| 77 std::max<int64_t>(next_packet_send_time_ + time_last_update_ms_ - |
| 78 clock_->TimeInMilliseconds(), |
| 79 0); |
| 80 if (rounding_error_time_ms_ == 1.0f || rounding_error_time_ms_ == -1.0f) { |
| 81 next_packet_send_time_ -= rounding_error_time_ms_; |
| 82 result = std::max<int64_t>(next_packet_send_time_ + time_last_update_ms_ - |
| 83 clock_->TimeInMilliseconds(), |
| 84 0); |
| 85 rounding_error_time_ms_ = 0; |
| 86 } |
| 87 return result; |
| 88 } |
| 89 |
| 90 void BbrPacedSender::OnBytesAcked(size_t bytes) { |
| 91 congestion_window_->AckReceived(bytes); |
| 92 } |
| 93 |
| 94 void BbrPacedSender::Process() { |
| 95 pacing_bitrate_kbps_ = |
| 96 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000); |
| 97 // If we have nothing to send, try sending again in 1 millisecond. |
| 98 if (packets_.empty()) { |
| 99 next_packet_send_time_ = 1; |
| 100 return; |
| 101 } |
| 102 // If congestion window doesn't allow sending, try again in 1 millisecond. |
| 103 if (packets_.front()->size_in_bytes + congestion_window_->data_inflight() > |
| 104 max_data_inflight_bytes_) { |
| 105 next_packet_send_time_ = 1; |
| 106 return; |
| 107 } |
| 108 bool sent = TryToSendPacket(packets_.front()); |
| 109 if (sent) { |
| 110 congestion_window_->PacketSent(packets_.front()->size_in_bytes); |
| 111 delete packets_.front(); |
| 112 packets_.pop_front(); |
| 113 time_last_update_ms_ = clock_->TimeInMilliseconds(); |
| 114 if (!packets_.empty()) { |
| 115 // Calculate in what time we should send current packet. |
| 116 next_packet_send_time_ = (packets_.front()->size_in_bytes * 8000 + |
| 117 estimated_bitrate_bps_ / 2) / |
| 118 estimated_bitrate_bps_; |
| 119 // As rounding errors may happen, |rounding_error_time_ms_| could be |
| 120 // positive or negative depending on packet was sent earlier or later, |
| 121 // after it hits certain threshold we will send a packet earlier or later |
| 122 // depending on error we had so far. |
| 123 rounding_error_time_ms_ += |
| 124 (next_packet_send_time_ - packets_.front()->size_in_bytes * 8000.0f / |
| 125 estimated_bitrate_bps_ * 1.0f); |
| 126 } else { |
| 127 // If sending was unsuccessful try again in 1 millisecond. |
| 128 next_packet_send_time_ = 1; |
| 129 } |
| 130 } |
| 131 } |
| 132 |
| 133 bool BbrPacedSender::TryToSendPacket(Packet* packet) { |
| 134 PacedPacketInfo pacing_info; |
| 135 return packet_sender_->TimeToSendPacket(packet->ssrc, packet->sequence_number, |
| 136 packet->capture_time_ms, |
| 137 packet->retransmission, pacing_info); |
| 138 } |
| 139 |
| 140 } // namespace webrtc |
OLD | NEW |