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