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 "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 "modules/pacing/paced_sender.h"
19 #include "modules/remote_bitrate_estimator/test/estimators/congestion_window.h"
20 #include "system_wrappers/include/clock.h"
21 
22 namespace webrtc {
23 
BbrPacedSender(const Clock * clock,PacedSender::PacketSender * packet_sender,RtcEventLog * event_log)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()) {}
~BbrPacedSender()39 BbrPacedSender::~BbrPacedSender() {}
40 
SetEstimatedBitrateAndCongestionWindow(uint32_t bitrate_bps,bool in_probe_rtt,uint64_t congestion_window)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 
SetMinBitrate(int min_send_bitrate_bps)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 
InsertPacket(RtpPacketSender::Priority priority,uint32_t ssrc,uint16_t sequence_number,int64_t capture_time_ms,size_t bytes,bool retransmission)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 
TimeUntilNextProcess()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 
OnBytesAcked(size_t bytes)90 void BbrPacedSender::OnBytesAcked(size_t bytes) {
91   congestion_window_->AckReceived(bytes);
92 }
93 
Process()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 
TryToSendPacket(Packet * packet)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
141