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/pacing/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/system_wrappers/include/clock.h" |
| 20 |
| 21 namespace webrtc { |
| 22 namespace bbr_paced_sender { |
| 23 struct Packet { |
| 24 Packet(RtpPacketSender::Priority priority, |
| 25 uint32_t ssrc, |
| 26 uint16_t seq_number, |
| 27 int64_t capture_time_ms, |
| 28 int64_t enqueue_time_ms, |
| 29 size_t size_in_bytes, |
| 30 bool retransmission) |
| 31 : priority(priority), |
| 32 ssrc(ssrc), |
| 33 sequence_number(seq_number), |
| 34 capture_time_ms(capture_time_ms), |
| 35 enqueue_time_ms(enqueue_time_ms), |
| 36 size_in_bytes(size_in_bytes), |
| 37 retransmission(retransmission) {} |
| 38 RtpPacketSender::Priority priority; |
| 39 uint32_t ssrc; |
| 40 uint16_t sequence_number; |
| 41 int64_t capture_time_ms; |
| 42 int64_t enqueue_time_ms; |
| 43 size_t size_in_bytes; |
| 44 bool retransmission; |
| 45 }; |
| 46 } // namespace bbr_paced_sender |
| 47 BbrPacedSender::BbrPacedSender(const Clock* clock, |
| 48 PacedSender::PacketSender* packet_sender, |
| 49 RtcEventLog* event_log) |
| 50 : clock_(clock), |
| 51 packet_sender_(packet_sender), |
| 52 estimated_bitrate_bps_(100000), |
| 53 min_send_bitrate_kbps_(0), |
| 54 pacing_bitrate_kbps_(0), |
| 55 time_last_update_us_(clock->TimeInMicroseconds()), |
| 56 time_last_update_ms_(clock->TimeInMilliseconds()), |
| 57 next_packet_send_time_(clock_->TimeInMilliseconds()), |
| 58 extra_time_(0.0f), |
| 59 packets_(), |
| 60 data_inflight_(0), |
| 61 // pacing_budget_(0), |
| 62 congestion_window_(6000), |
| 63 in_probe_rtt_(false) {} |
| 64 BbrPacedSender::~BbrPacedSender() {} |
| 65 |
| 66 void BbrPacedSender::SetEstimatedBitrateAndCongestionWindow( |
| 67 uint32_t bitrate_bps, |
| 68 bool in_probe_rtt, |
| 69 uint64_t congestion_window) { |
| 70 estimated_bitrate_bps_ = bitrate_bps; |
| 71 congestion_window_ = congestion_window; |
| 72 in_probe_rtt_ = in_probe_rtt; |
| 73 } |
| 74 |
| 75 void BbrPacedSender::SetMinBitrate(int min_send_bitrate_bps) { |
| 76 min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; |
| 77 pacing_bitrate_kbps_ = |
| 78 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000); |
| 79 } |
| 80 |
| 81 void BbrPacedSender::InsertPacket(RtpPacketSender::Priority priority, |
| 82 uint32_t ssrc, |
| 83 uint16_t sequence_number, |
| 84 int64_t capture_time_ms, |
| 85 size_t bytes, |
| 86 bool retransmission) { |
| 87 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 88 if (capture_time_ms < 0) |
| 89 capture_time_ms = now_ms; |
| 90 packets_.push_back(new bbr_paced_sender::Packet( |
| 91 priority, ssrc, sequence_number, capture_time_ms, now_ms, bytes, |
| 92 retransmission)); |
| 93 } |
| 94 |
| 95 int64_t BbrPacedSender::TimeUntilNextProcess() { |
| 96 // Once errors absolute value hits 2 milliseconds, add compensating term to |
| 97 // the |next_packet_send_time_|, so that we can send packet earlier or later, |
| 98 // depending on the error. |
| 99 extra_time_ = std::min(extra_time_, 2.0f); |
| 100 if (extra_time_ < -1.9f) |
| 101 extra_time_ = -2.0f; |
| 102 int64_t result = |
| 103 std::max<int64_t>(next_packet_send_time_ + time_last_update_ms_ - |
| 104 clock_->TimeInMilliseconds(), |
| 105 0); |
| 106 if (extra_time_ == 2.0f || extra_time_ == -2.0f) { |
| 107 next_packet_send_time_ -= extra_time_; |
| 108 result = std::max<int64_t>(next_packet_send_time_ + time_last_update_ms_ - |
| 109 clock_->TimeInMilliseconds(), |
| 110 0); |
| 111 extra_time_ = 0; |
| 112 } |
| 113 return result; |
| 114 } |
| 115 |
| 116 void BbrPacedSender::OnBytesAcked(size_t bytes) { |
| 117 assert(data_inflight_ >= bytes); |
| 118 data_inflight_ -= bytes; |
| 119 } |
| 120 |
| 121 void BbrPacedSender::Process() { |
| 122 pacing_bitrate_kbps_ = |
| 123 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000); |
| 124 // If we have nothing to send, try sending again in 1 millisecond. |
| 125 if (packets_.empty()) { |
| 126 next_packet_send_time_ = 1; |
| 127 return; |
| 128 } |
| 129 // If congestion window doesn't allow sending, try again in 1 millisecond. |
| 130 if (packets_.front()->size_in_bytes + data_inflight_ > congestion_window_) { |
| 131 next_packet_send_time_ = 1; |
| 132 return; |
| 133 } |
| 134 bool sent = TryToSendPacket(packets_.front()); |
| 135 if (sent) { |
| 136 data_inflight_ += packets_.front()->size_in_bytes; |
| 137 delete packets_.front(); |
| 138 packets_.pop_front(); |
| 139 time_last_update_ms_ = clock_->TimeInMilliseconds(); |
| 140 if (!packets_.empty()) { |
| 141 // Calculate in what time we should send current packet. |
| 142 next_packet_send_time_ = (packets_.front()->size_in_bytes * 8000 + |
| 143 estimated_bitrate_bps_ / 2) / |
| 144 estimated_bitrate_bps_; |
| 145 // As rounding errors may happen, |extra_time_| could be positive or |
| 146 // negative depending on packet was sent earlier or later, after it hits |
| 147 // certain threshold we will send a packet earlier or later depending on |
| 148 // error we had so far. |
| 149 extra_time_ += |
| 150 (next_packet_send_time_ - packets_.front()->size_in_bytes * 8000.0f / |
| 151 estimated_bitrate_bps_ * 1.0f); |
| 152 } else { |
| 153 // If sending was unsuccessful try again in 1 millisecond. |
| 154 next_packet_send_time_ = 1; |
| 155 } |
| 156 } |
| 157 } |
| 158 |
| 159 bool BbrPacedSender::TryToSendPacket(bbr_paced_sender::Packet* packet) { |
| 160 PacedPacketInfo pacing_info; |
| 161 return packet_sender_->TimeToSendPacket(packet->ssrc, packet->sequence_number, |
| 162 packet->capture_time_ms, |
| 163 packet->retransmission, pacing_info); |
| 164 } |
| 165 |
| 166 } // namespace webrtc |
OLD | NEW |