blob: ce8af0bfb7d2aa74b87b9fe63926acb6943808d4 [file] [log] [blame]
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +00001/*
2 * Copyright (c) 2013 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/remote_bitrate_estimator/inter_arrival.h"
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000012
Yves Gerey988cc082018-10-23 12:03:01 +020013#include "modules/include/module_common_types_public.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "rtc_base/logging.h"
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000015
16namespace webrtc {
17
stefan1112b2b2016-04-14 08:08:15 -070018static const int kBurstDeltaThresholdMs = 5;
Sebastian Janssonbe20ef72018-09-06 12:32:31 +020019static const int kMaxBurstDurationMs = 100;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000020
21InterArrival::InterArrival(uint32_t timestamp_group_length_ticks,
22 double timestamp_to_ms_coeff,
23 bool enable_burst_grouping)
24 : kTimestampGroupLengthTicks(timestamp_group_length_ticks),
25 current_timestamp_group_(),
26 prev_timestamp_group_(),
27 timestamp_to_ms_coeff_(timestamp_to_ms_coeff),
stefan5e12d362016-07-11 01:44:02 -070028 burst_grouping_(enable_burst_grouping),
29 num_consecutive_reordered_packets_(0) {}
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000030
31bool InterArrival::ComputeDeltas(uint32_t timestamp,
32 int64_t arrival_time_ms,
stefan5e12d362016-07-11 01:44:02 -070033 int64_t system_time_ms,
stefan64c0a0a2015-11-27 01:02:31 -080034 size_t packet_size,
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000035 uint32_t* timestamp_delta,
stefan64c0a0a2015-11-27 01:02:31 -080036 int64_t* arrival_time_delta_ms,
37 int* packet_size_delta) {
Mirko Bonadei25ab3222021-07-08 20:08:20 +020038 RTC_DCHECK(timestamp_delta);
39 RTC_DCHECK(arrival_time_delta_ms);
40 RTC_DCHECK(packet_size_delta);
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000041 bool calculated_deltas = false;
42 if (current_timestamp_group_.IsFirstPacket()) {
43 // We don't have enough data to update the filter, so we store it until we
44 // have two frames of data to process.
45 current_timestamp_group_.timestamp = timestamp;
46 current_timestamp_group_.first_timestamp = timestamp;
Sebastian Janssonbe20ef72018-09-06 12:32:31 +020047 current_timestamp_group_.first_arrival_ms = arrival_time_ms;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000048 } else if (!PacketInOrder(timestamp)) {
49 return false;
50 } else if (NewTimestampGroup(arrival_time_ms, timestamp)) {
51 // First packet of a later frame, the previous frame sample is ready.
52 if (prev_timestamp_group_.complete_time_ms >= 0) {
Yves Gerey665174f2018-06-19 15:03:05 +020053 *timestamp_delta =
54 current_timestamp_group_.timestamp - prev_timestamp_group_.timestamp;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000055 *arrival_time_delta_ms = current_timestamp_group_.complete_time_ms -
56 prev_timestamp_group_.complete_time_ms;
stefan5e12d362016-07-11 01:44:02 -070057 // Check system time differences to see if we have an unproportional jump
58 // in arrival time. In that case reset the inter-arrival computations.
59 int64_t system_time_delta_ms =
60 current_timestamp_group_.last_system_time_ms -
61 prev_timestamp_group_.last_system_time_ms;
62 if (*arrival_time_delta_ms - system_time_delta_ms >=
63 kArrivalTimeOffsetThresholdMs) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010064 RTC_LOG(LS_WARNING)
65 << "The arrival time clock offset has changed (diff = "
66 << *arrival_time_delta_ms - system_time_delta_ms
67 << " ms), resetting.";
stefan5e12d362016-07-11 01:44:02 -070068 Reset();
69 return false;
70 }
stefancfd5f962015-07-24 03:26:46 -070071 if (*arrival_time_delta_ms < 0) {
72 // The group of packets has been reordered since receiving its local
73 // arrival timestamp.
stefan5e12d362016-07-11 01:44:02 -070074 ++num_consecutive_reordered_packets_;
75 if (num_consecutive_reordered_packets_ >= kReorderedResetThreshold) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010076 RTC_LOG(LS_WARNING)
77 << "Packets are being reordered on the path from the "
78 "socket to the bandwidth estimator. Ignoring this "
79 "packet for bandwidth estimation, resetting.";
stefan5e12d362016-07-11 01:44:02 -070080 Reset();
81 }
stefancfd5f962015-07-24 03:26:46 -070082 return false;
stefan5e12d362016-07-11 01:44:02 -070083 } else {
84 num_consecutive_reordered_packets_ = 0;
stefancfd5f962015-07-24 03:26:46 -070085 }
Mirko Bonadei25ab3222021-07-08 20:08:20 +020086 RTC_DCHECK_GE(*arrival_time_delta_ms, 0);
stefan64c0a0a2015-11-27 01:02:31 -080087 *packet_size_delta = static_cast<int>(current_timestamp_group_.size) -
Yves Gerey665174f2018-06-19 15:03:05 +020088 static_cast<int>(prev_timestamp_group_.size);
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000089 calculated_deltas = true;
90 }
91 prev_timestamp_group_ = current_timestamp_group_;
92 // The new timestamp is now the current frame.
93 current_timestamp_group_.first_timestamp = timestamp;
94 current_timestamp_group_.timestamp = timestamp;
Sebastian Janssonbe20ef72018-09-06 12:32:31 +020095 current_timestamp_group_.first_arrival_ms = arrival_time_ms;
stefan64c0a0a2015-11-27 01:02:31 -080096 current_timestamp_group_.size = 0;
terelius8f09f172015-12-15 00:51:54 -080097 } else {
Yves Gerey665174f2018-06-19 15:03:05 +020098 current_timestamp_group_.timestamp =
99 LatestTimestamp(current_timestamp_group_.timestamp, timestamp);
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000100 }
stefan64c0a0a2015-11-27 01:02:31 -0800101 // Accumulate the frame size.
102 current_timestamp_group_.size += packet_size;
103 current_timestamp_group_.complete_time_ms = arrival_time_ms;
stefan5e12d362016-07-11 01:44:02 -0700104 current_timestamp_group_.last_system_time_ms = system_time_ms;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000105
106 return calculated_deltas;
107}
108
109bool InterArrival::PacketInOrder(uint32_t timestamp) {
110 if (current_timestamp_group_.IsFirstPacket()) {
111 return true;
112 } else {
113 // Assume that a diff which is bigger than half the timestamp interval
114 // (32 bits) must be due to reordering. This code is almost identical to
115 // that in IsNewerTimestamp() in module_common_types.h.
Yves Gerey665174f2018-06-19 15:03:05 +0200116 uint32_t timestamp_diff =
117 timestamp - current_timestamp_group_.first_timestamp;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000118 return timestamp_diff < 0x80000000;
119 }
120}
121
122// Assumes that |timestamp| is not reordered compared to
123// |current_timestamp_group_|.
124bool InterArrival::NewTimestampGroup(int64_t arrival_time_ms,
125 uint32_t timestamp) const {
126 if (current_timestamp_group_.IsFirstPacket()) {
127 return false;
128 } else if (BelongsToBurst(arrival_time_ms, timestamp)) {
129 return false;
130 } else {
Yves Gerey665174f2018-06-19 15:03:05 +0200131 uint32_t timestamp_diff =
132 timestamp - current_timestamp_group_.first_timestamp;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000133 return timestamp_diff > kTimestampGroupLengthTicks;
134 }
135}
136
137bool InterArrival::BelongsToBurst(int64_t arrival_time_ms,
138 uint32_t timestamp) const {
139 if (!burst_grouping_) {
140 return false;
141 }
Mirko Bonadei25ab3222021-07-08 20:08:20 +0200142 RTC_DCHECK_GE(current_timestamp_group_.complete_time_ms, 0);
Yves Gerey665174f2018-06-19 15:03:05 +0200143 int64_t arrival_time_delta_ms =
144 arrival_time_ms - current_timestamp_group_.complete_time_ms;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000145 uint32_t timestamp_diff = timestamp - current_timestamp_group_.timestamp;
146 int64_t ts_delta_ms = timestamp_to_ms_coeff_ * timestamp_diff + 0.5;
147 if (ts_delta_ms == 0)
148 return true;
149 int propagation_delta_ms = arrival_time_delta_ms - ts_delta_ms;
Sebastian Janssonbe20ef72018-09-06 12:32:31 +0200150 if (propagation_delta_ms < 0 &&
151 arrival_time_delta_ms <= kBurstDeltaThresholdMs &&
152 arrival_time_ms - current_timestamp_group_.first_arrival_ms <
153 kMaxBurstDurationMs)
154 return true;
155 return false;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000156}
stefan5e12d362016-07-11 01:44:02 -0700157
158void InterArrival::Reset() {
159 num_consecutive_reordered_packets_ = 0;
160 current_timestamp_group_ = TimestampGroup();
161 prev_timestamp_group_ = TimestampGroup();
162}
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000163} // namespace webrtc