summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc')
-rw-r--r--third_party/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc158
1 files changed, 158 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc b/third_party/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc
new file mode 100644
index 0000000000..06ff580b92
--- /dev/null
+++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2013 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/remote_bitrate_estimator/inter_arrival.h"
+
+#include "modules/include/module_common_types_public.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+
+static const int kBurstDeltaThresholdMs = 5;
+static const int kMaxBurstDurationMs = 100;
+
+InterArrival::InterArrival(uint32_t timestamp_group_length_ticks,
+ double timestamp_to_ms_coeff)
+ : kTimestampGroupLengthTicks(timestamp_group_length_ticks),
+ current_timestamp_group_(),
+ prev_timestamp_group_(),
+ timestamp_to_ms_coeff_(timestamp_to_ms_coeff),
+ num_consecutive_reordered_packets_(0) {}
+
+bool InterArrival::ComputeDeltas(uint32_t timestamp,
+ int64_t arrival_time_ms,
+ int64_t system_time_ms,
+ size_t packet_size,
+ uint32_t* timestamp_delta,
+ int64_t* arrival_time_delta_ms,
+ int* packet_size_delta) {
+ RTC_DCHECK(timestamp_delta);
+ RTC_DCHECK(arrival_time_delta_ms);
+ RTC_DCHECK(packet_size_delta);
+ bool calculated_deltas = false;
+ if (current_timestamp_group_.IsFirstPacket()) {
+ // We don't have enough data to update the filter, so we store it until we
+ // have two frames of data to process.
+ current_timestamp_group_.timestamp = timestamp;
+ current_timestamp_group_.first_timestamp = timestamp;
+ current_timestamp_group_.first_arrival_ms = arrival_time_ms;
+ } else if (!PacketInOrder(timestamp)) {
+ return false;
+ } else if (NewTimestampGroup(arrival_time_ms, timestamp)) {
+ // First packet of a later frame, the previous frame sample is ready.
+ if (prev_timestamp_group_.complete_time_ms >= 0) {
+ *timestamp_delta =
+ current_timestamp_group_.timestamp - prev_timestamp_group_.timestamp;
+ *arrival_time_delta_ms = current_timestamp_group_.complete_time_ms -
+ prev_timestamp_group_.complete_time_ms;
+ // Check system time differences to see if we have an unproportional jump
+ // in arrival time. In that case reset the inter-arrival computations.
+ int64_t system_time_delta_ms =
+ current_timestamp_group_.last_system_time_ms -
+ prev_timestamp_group_.last_system_time_ms;
+ if (*arrival_time_delta_ms - system_time_delta_ms >=
+ kArrivalTimeOffsetThresholdMs) {
+ RTC_LOG(LS_WARNING)
+ << "The arrival time clock offset has changed (diff = "
+ << *arrival_time_delta_ms - system_time_delta_ms
+ << " ms), resetting.";
+ Reset();
+ return false;
+ }
+ if (*arrival_time_delta_ms < 0) {
+ // The group of packets has been reordered since receiving its local
+ // arrival timestamp.
+ ++num_consecutive_reordered_packets_;
+ if (num_consecutive_reordered_packets_ >= kReorderedResetThreshold) {
+ RTC_LOG(LS_WARNING)
+ << "Packets are being reordered on the path from the "
+ "socket to the bandwidth estimator. Ignoring this "
+ "packet for bandwidth estimation, resetting.";
+ Reset();
+ }
+ return false;
+ } else {
+ num_consecutive_reordered_packets_ = 0;
+ }
+ RTC_DCHECK_GE(*arrival_time_delta_ms, 0);
+ *packet_size_delta = static_cast<int>(current_timestamp_group_.size) -
+ static_cast<int>(prev_timestamp_group_.size);
+ calculated_deltas = true;
+ }
+ prev_timestamp_group_ = current_timestamp_group_;
+ // The new timestamp is now the current frame.
+ current_timestamp_group_.first_timestamp = timestamp;
+ current_timestamp_group_.timestamp = timestamp;
+ current_timestamp_group_.first_arrival_ms = arrival_time_ms;
+ current_timestamp_group_.size = 0;
+ } else {
+ current_timestamp_group_.timestamp =
+ LatestTimestamp(current_timestamp_group_.timestamp, timestamp);
+ }
+ // Accumulate the frame size.
+ current_timestamp_group_.size += packet_size;
+ current_timestamp_group_.complete_time_ms = arrival_time_ms;
+ current_timestamp_group_.last_system_time_ms = system_time_ms;
+
+ return calculated_deltas;
+}
+
+bool InterArrival::PacketInOrder(uint32_t timestamp) {
+ if (current_timestamp_group_.IsFirstPacket()) {
+ return true;
+ } else {
+ // Assume that a diff which is bigger than half the timestamp interval
+ // (32 bits) must be due to reordering. This code is almost identical to
+ // that in IsNewerTimestamp() in module_common_types.h.
+ uint32_t timestamp_diff =
+ timestamp - current_timestamp_group_.first_timestamp;
+ return timestamp_diff < 0x80000000;
+ }
+}
+
+// Assumes that `timestamp` is not reordered compared to
+// `current_timestamp_group_`.
+bool InterArrival::NewTimestampGroup(int64_t arrival_time_ms,
+ uint32_t timestamp) const {
+ if (current_timestamp_group_.IsFirstPacket()) {
+ return false;
+ } else if (BelongsToBurst(arrival_time_ms, timestamp)) {
+ return false;
+ } else {
+ uint32_t timestamp_diff =
+ timestamp - current_timestamp_group_.first_timestamp;
+ return timestamp_diff > kTimestampGroupLengthTicks;
+ }
+}
+
+bool InterArrival::BelongsToBurst(int64_t arrival_time_ms,
+ uint32_t timestamp) const {
+ RTC_DCHECK_GE(current_timestamp_group_.complete_time_ms, 0);
+ int64_t arrival_time_delta_ms =
+ arrival_time_ms - current_timestamp_group_.complete_time_ms;
+ uint32_t timestamp_diff = timestamp - current_timestamp_group_.timestamp;
+ int64_t ts_delta_ms = timestamp_to_ms_coeff_ * timestamp_diff + 0.5;
+ if (ts_delta_ms == 0)
+ return true;
+ int propagation_delta_ms = arrival_time_delta_ms - ts_delta_ms;
+ if (propagation_delta_ms < 0 &&
+ arrival_time_delta_ms <= kBurstDeltaThresholdMs &&
+ arrival_time_ms - current_timestamp_group_.first_arrival_ms <
+ kMaxBurstDurationMs)
+ return true;
+ return false;
+}
+
+void InterArrival::Reset() {
+ num_consecutive_reordered_packets_ = 0;
+ current_timestamp_group_ = TimestampGroup();
+ prev_timestamp_group_ = TimestampGroup();
+}
+} // namespace webrtc