summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/congestion_controller/pcc/monitor_interval.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/congestion_controller/pcc/monitor_interval.cc')
-rw-r--r--third_party/libwebrtc/modules/congestion_controller/pcc/monitor_interval.cc135
1 files changed, 135 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/congestion_controller/pcc/monitor_interval.cc b/third_party/libwebrtc/modules/congestion_controller/pcc/monitor_interval.cc
new file mode 100644
index 0000000000..de1e2d5e69
--- /dev/null
+++ b/third_party/libwebrtc/modules/congestion_controller/pcc/monitor_interval.cc
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/congestion_controller/pcc/monitor_interval.h"
+
+#include <stddef.h>
+
+#include <cmath>
+
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+namespace pcc {
+
+PccMonitorInterval::PccMonitorInterval(DataRate target_sending_rate,
+ Timestamp start_time,
+ TimeDelta duration)
+ : target_sending_rate_(target_sending_rate),
+ start_time_(start_time),
+ interval_duration_(duration),
+ received_packets_size_(DataSize::Zero()),
+ feedback_collection_done_(false) {}
+
+PccMonitorInterval::~PccMonitorInterval() = default;
+
+PccMonitorInterval::PccMonitorInterval(const PccMonitorInterval& other) =
+ default;
+
+void PccMonitorInterval::OnPacketsFeedback(
+ const std::vector<PacketResult>& packets_results) {
+ for (const PacketResult& packet_result : packets_results) {
+ if (packet_result.sent_packet.send_time <= start_time_) {
+ continue;
+ }
+ // Here we assume that if some packets are reordered with packets sent
+ // after the end of the monitor interval, then they are lost. (Otherwise
+ // it is not clear how long should we wait for packets feedback to arrive).
+ if (packet_result.sent_packet.send_time >
+ start_time_ + interval_duration_) {
+ feedback_collection_done_ = true;
+ return;
+ }
+ if (!packet_result.IsReceived()) {
+ lost_packets_sent_time_.push_back(packet_result.sent_packet.send_time);
+ } else {
+ received_packets_.push_back(
+ {packet_result.receive_time - packet_result.sent_packet.send_time,
+ packet_result.sent_packet.send_time});
+ received_packets_size_ += packet_result.sent_packet.size;
+ }
+ }
+}
+
+// For the formula used in computations see formula for "slope" in the second
+// method:
+// https://www.johndcook.com/blog/2008/10/20/comparing-two-ways-to-fit-a-line-to-data/
+double PccMonitorInterval::ComputeDelayGradient(
+ double delay_gradient_threshold) const {
+ // Early return to prevent division by 0 in case all packets are sent at the
+ // same time.
+ if (received_packets_.empty() || received_packets_.front().sent_time ==
+ received_packets_.back().sent_time) {
+ return 0;
+ }
+ double sum_times = 0;
+ for (const ReceivedPacket& packet : received_packets_) {
+ double time_delta_us =
+ (packet.sent_time - received_packets_[0].sent_time).us();
+ sum_times += time_delta_us;
+ }
+ double sum_squared_scaled_time_deltas = 0;
+ double sum_scaled_time_delta_dot_delay = 0;
+ for (const ReceivedPacket& packet : received_packets_) {
+ double time_delta_us =
+ (packet.sent_time - received_packets_[0].sent_time).us();
+ double delay = packet.delay.us();
+ double scaled_time_delta_us =
+ time_delta_us - sum_times / received_packets_.size();
+ sum_squared_scaled_time_deltas +=
+ scaled_time_delta_us * scaled_time_delta_us;
+ sum_scaled_time_delta_dot_delay += scaled_time_delta_us * delay;
+ }
+ double rtt_gradient =
+ sum_scaled_time_delta_dot_delay / sum_squared_scaled_time_deltas;
+ if (std::abs(rtt_gradient) < delay_gradient_threshold)
+ rtt_gradient = 0;
+ return rtt_gradient;
+}
+
+bool PccMonitorInterval::IsFeedbackCollectionDone() const {
+ return feedback_collection_done_;
+}
+
+Timestamp PccMonitorInterval::GetEndTime() const {
+ return start_time_ + interval_duration_;
+}
+
+double PccMonitorInterval::GetLossRate() const {
+ size_t packets_lost = lost_packets_sent_time_.size();
+ size_t packets_received = received_packets_.size();
+ if (packets_lost == 0)
+ return 0;
+ return static_cast<double>(packets_lost) / (packets_lost + packets_received);
+}
+
+DataRate PccMonitorInterval::GetTargetSendingRate() const {
+ return target_sending_rate_;
+}
+
+DataRate PccMonitorInterval::GetTransmittedPacketsRate() const {
+ if (received_packets_.empty()) {
+ return target_sending_rate_;
+ }
+ Timestamp receive_time_of_first_packet =
+ received_packets_.front().sent_time + received_packets_.front().delay;
+ Timestamp receive_time_of_last_packet =
+ received_packets_.back().sent_time + received_packets_.back().delay;
+ if (receive_time_of_first_packet == receive_time_of_last_packet) {
+ RTC_LOG(LS_WARNING)
+ << "All packets in monitor interval were received at the same time.";
+ return target_sending_rate_;
+ }
+ return received_packets_size_ /
+ (receive_time_of_last_packet - receive_time_of_first_packet);
+}
+
+} // namespace pcc
+} // namespace webrtc