monitor_interval.cc (5102B)
1 /* 2 * Copyright (c) 2018 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/congestion_controller/pcc/monitor_interval.h" 12 13 #include <cmath> 14 #include <cstddef> 15 #include <vector> 16 17 #include "api/transport/network_types.h" 18 #include "api/units/data_rate.h" 19 #include "api/units/data_size.h" 20 #include "api/units/time_delta.h" 21 #include "api/units/timestamp.h" 22 #include "rtc_base/logging.h" 23 24 namespace webrtc { 25 namespace pcc { 26 27 PccMonitorInterval::PccMonitorInterval(DataRate target_sending_rate, 28 Timestamp start_time, 29 TimeDelta duration) 30 : target_sending_rate_(target_sending_rate), 31 start_time_(start_time), 32 interval_duration_(duration), 33 received_packets_size_(DataSize::Zero()), 34 feedback_collection_done_(false) {} 35 36 PccMonitorInterval::~PccMonitorInterval() = default; 37 38 PccMonitorInterval::PccMonitorInterval(const PccMonitorInterval& other) = 39 default; 40 41 void PccMonitorInterval::OnPacketsFeedback( 42 const std::vector<PacketResult>& packets_results) { 43 for (const PacketResult& packet_result : packets_results) { 44 if (packet_result.sent_packet.send_time <= start_time_) { 45 continue; 46 } 47 // Here we assume that if some packets are reordered with packets sent 48 // after the end of the monitor interval, then they are lost. (Otherwise 49 // it is not clear how long should we wait for packets feedback to arrive). 50 if (packet_result.sent_packet.send_time > 51 start_time_ + interval_duration_) { 52 feedback_collection_done_ = true; 53 return; 54 } 55 if (!packet_result.IsReceived()) { 56 lost_packets_sent_time_.push_back(packet_result.sent_packet.send_time); 57 } else { 58 received_packets_.push_back( 59 {packet_result.receive_time - packet_result.sent_packet.send_time, 60 packet_result.sent_packet.send_time}); 61 received_packets_size_ += packet_result.sent_packet.size; 62 } 63 } 64 } 65 66 // For the formula used in computations see formula for "slope" in the second 67 // method: 68 // https://www.johndcook.com/blog/2008/10/20/comparing-two-ways-to-fit-a-line-to-data/ 69 double PccMonitorInterval::ComputeDelayGradient( 70 double delay_gradient_threshold) const { 71 // Early return to prevent division by 0 in case all packets are sent at the 72 // same time. 73 if (received_packets_.empty() || received_packets_.front().sent_time == 74 received_packets_.back().sent_time) { 75 return 0; 76 } 77 double sum_times = 0; 78 for (const ReceivedPacket& packet : received_packets_) { 79 double time_delta_us = 80 (packet.sent_time - received_packets_[0].sent_time).us(); 81 sum_times += time_delta_us; 82 } 83 double sum_squared_scaled_time_deltas = 0; 84 double sum_scaled_time_delta_dot_delay = 0; 85 for (const ReceivedPacket& packet : received_packets_) { 86 double time_delta_us = 87 (packet.sent_time - received_packets_[0].sent_time).us(); 88 double delay = packet.delay.us(); 89 double scaled_time_delta_us = 90 time_delta_us - sum_times / received_packets_.size(); 91 sum_squared_scaled_time_deltas += 92 scaled_time_delta_us * scaled_time_delta_us; 93 sum_scaled_time_delta_dot_delay += scaled_time_delta_us * delay; 94 } 95 double rtt_gradient = 96 sum_scaled_time_delta_dot_delay / sum_squared_scaled_time_deltas; 97 if (std::abs(rtt_gradient) < delay_gradient_threshold) 98 rtt_gradient = 0; 99 return rtt_gradient; 100 } 101 102 bool PccMonitorInterval::IsFeedbackCollectionDone() const { 103 return feedback_collection_done_; 104 } 105 106 Timestamp PccMonitorInterval::GetEndTime() const { 107 return start_time_ + interval_duration_; 108 } 109 110 double PccMonitorInterval::GetLossRate() const { 111 size_t packets_lost = lost_packets_sent_time_.size(); 112 size_t packets_received = received_packets_.size(); 113 if (packets_lost == 0) 114 return 0; 115 return static_cast<double>(packets_lost) / (packets_lost + packets_received); 116 } 117 118 DataRate PccMonitorInterval::GetTargetSendingRate() const { 119 return target_sending_rate_; 120 } 121 122 DataRate PccMonitorInterval::GetTransmittedPacketsRate() const { 123 if (received_packets_.empty()) { 124 return target_sending_rate_; 125 } 126 Timestamp receive_time_of_first_packet = 127 received_packets_.front().sent_time + received_packets_.front().delay; 128 Timestamp receive_time_of_last_packet = 129 received_packets_.back().sent_time + received_packets_.back().delay; 130 if (receive_time_of_first_packet == receive_time_of_last_packet) { 131 RTC_LOG(LS_WARNING) 132 << "All packets in monitor interval were received at the same time."; 133 return target_sending_rate_; 134 } 135 return received_packets_size_ / 136 (receive_time_of_last_packet - receive_time_of_first_packet); 137 } 138 139 } // namespace pcc 140 } // namespace webrtc