blob: 3a0f579052f90f4d90499c516941718fa740dbcd [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
13#include <algorithm>
14#include <cassert>
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "modules/include/module_common_types.h"
17#include "rtc_base/logging.h"
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000018
19namespace webrtc {
20
stefan1112b2b2016-04-14 08:08:15 -070021static const int kBurstDeltaThresholdMs = 5;
Sebastian Janssonbe20ef72018-09-06 12:32:31 +020022static const int kMaxBurstDurationMs = 100;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000023
24InterArrival::InterArrival(uint32_t timestamp_group_length_ticks,
25 double timestamp_to_ms_coeff,
26 bool enable_burst_grouping)
27 : kTimestampGroupLengthTicks(timestamp_group_length_ticks),
28 current_timestamp_group_(),
29 prev_timestamp_group_(),
30 timestamp_to_ms_coeff_(timestamp_to_ms_coeff),
stefan5e12d362016-07-11 01:44:02 -070031 burst_grouping_(enable_burst_grouping),
32 num_consecutive_reordered_packets_(0) {}
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000033
34bool InterArrival::ComputeDeltas(uint32_t timestamp,
35 int64_t arrival_time_ms,
stefan5e12d362016-07-11 01:44:02 -070036 int64_t system_time_ms,
stefan64c0a0a2015-11-27 01:02:31 -080037 size_t packet_size,
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000038 uint32_t* timestamp_delta,
stefan64c0a0a2015-11-27 01:02:31 -080039 int64_t* arrival_time_delta_ms,
40 int* packet_size_delta) {
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000041 assert(timestamp_delta != NULL);
42 assert(arrival_time_delta_ms != NULL);
stefan64c0a0a2015-11-27 01:02:31 -080043 assert(packet_size_delta != NULL);
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000044 bool calculated_deltas = false;
45 if (current_timestamp_group_.IsFirstPacket()) {
46 // We don't have enough data to update the filter, so we store it until we
47 // have two frames of data to process.
48 current_timestamp_group_.timestamp = timestamp;
49 current_timestamp_group_.first_timestamp = timestamp;
Sebastian Janssonbe20ef72018-09-06 12:32:31 +020050 current_timestamp_group_.first_arrival_ms = arrival_time_ms;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000051 } else if (!PacketInOrder(timestamp)) {
52 return false;
53 } else if (NewTimestampGroup(arrival_time_ms, timestamp)) {
54 // First packet of a later frame, the previous frame sample is ready.
55 if (prev_timestamp_group_.complete_time_ms >= 0) {
Yves Gerey665174f2018-06-19 15:03:05 +020056 *timestamp_delta =
57 current_timestamp_group_.timestamp - prev_timestamp_group_.timestamp;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000058 *arrival_time_delta_ms = current_timestamp_group_.complete_time_ms -
59 prev_timestamp_group_.complete_time_ms;
stefan5e12d362016-07-11 01:44:02 -070060 // Check system time differences to see if we have an unproportional jump
61 // in arrival time. In that case reset the inter-arrival computations.
62 int64_t system_time_delta_ms =
63 current_timestamp_group_.last_system_time_ms -
64 prev_timestamp_group_.last_system_time_ms;
65 if (*arrival_time_delta_ms - system_time_delta_ms >=
66 kArrivalTimeOffsetThresholdMs) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010067 RTC_LOG(LS_WARNING)
68 << "The arrival time clock offset has changed (diff = "
69 << *arrival_time_delta_ms - system_time_delta_ms
70 << " ms), resetting.";
stefan5e12d362016-07-11 01:44:02 -070071 Reset();
72 return false;
73 }
stefancfd5f962015-07-24 03:26:46 -070074 if (*arrival_time_delta_ms < 0) {
75 // The group of packets has been reordered since receiving its local
76 // arrival timestamp.
stefan5e12d362016-07-11 01:44:02 -070077 ++num_consecutive_reordered_packets_;
78 if (num_consecutive_reordered_packets_ >= kReorderedResetThreshold) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010079 RTC_LOG(LS_WARNING)
80 << "Packets are being reordered on the path from the "
81 "socket to the bandwidth estimator. Ignoring this "
82 "packet for bandwidth estimation, resetting.";
stefan5e12d362016-07-11 01:44:02 -070083 Reset();
84 }
stefancfd5f962015-07-24 03:26:46 -070085 return false;
stefan5e12d362016-07-11 01:44:02 -070086 } else {
87 num_consecutive_reordered_packets_ = 0;
stefancfd5f962015-07-24 03:26:46 -070088 }
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000089 assert(*arrival_time_delta_ms >= 0);
stefan64c0a0a2015-11-27 01:02:31 -080090 *packet_size_delta = static_cast<int>(current_timestamp_group_.size) -
Yves Gerey665174f2018-06-19 15:03:05 +020091 static_cast<int>(prev_timestamp_group_.size);
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +000092 calculated_deltas = true;
93 }
94 prev_timestamp_group_ = current_timestamp_group_;
95 // The new timestamp is now the current frame.
96 current_timestamp_group_.first_timestamp = timestamp;
97 current_timestamp_group_.timestamp = timestamp;
Sebastian Janssonbe20ef72018-09-06 12:32:31 +020098 current_timestamp_group_.first_arrival_ms = arrival_time_ms;
stefan64c0a0a2015-11-27 01:02:31 -080099 current_timestamp_group_.size = 0;
terelius8f09f172015-12-15 00:51:54 -0800100 } else {
Yves Gerey665174f2018-06-19 15:03:05 +0200101 current_timestamp_group_.timestamp =
102 LatestTimestamp(current_timestamp_group_.timestamp, timestamp);
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000103 }
stefan64c0a0a2015-11-27 01:02:31 -0800104 // Accumulate the frame size.
105 current_timestamp_group_.size += packet_size;
106 current_timestamp_group_.complete_time_ms = arrival_time_ms;
stefan5e12d362016-07-11 01:44:02 -0700107 current_timestamp_group_.last_system_time_ms = system_time_ms;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000108
109 return calculated_deltas;
110}
111
112bool InterArrival::PacketInOrder(uint32_t timestamp) {
113 if (current_timestamp_group_.IsFirstPacket()) {
114 return true;
115 } else {
116 // Assume that a diff which is bigger than half the timestamp interval
117 // (32 bits) must be due to reordering. This code is almost identical to
118 // that in IsNewerTimestamp() in module_common_types.h.
Yves Gerey665174f2018-06-19 15:03:05 +0200119 uint32_t timestamp_diff =
120 timestamp - current_timestamp_group_.first_timestamp;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000121 return timestamp_diff < 0x80000000;
122 }
123}
124
125// Assumes that |timestamp| is not reordered compared to
126// |current_timestamp_group_|.
127bool InterArrival::NewTimestampGroup(int64_t arrival_time_ms,
128 uint32_t timestamp) const {
129 if (current_timestamp_group_.IsFirstPacket()) {
130 return false;
131 } else if (BelongsToBurst(arrival_time_ms, timestamp)) {
132 return false;
133 } else {
Yves Gerey665174f2018-06-19 15:03:05 +0200134 uint32_t timestamp_diff =
135 timestamp - current_timestamp_group_.first_timestamp;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000136 return timestamp_diff > kTimestampGroupLengthTicks;
137 }
138}
139
140bool InterArrival::BelongsToBurst(int64_t arrival_time_ms,
141 uint32_t timestamp) const {
142 if (!burst_grouping_) {
143 return false;
144 }
145 assert(current_timestamp_group_.complete_time_ms >= 0);
Yves Gerey665174f2018-06-19 15:03:05 +0200146 int64_t arrival_time_delta_ms =
147 arrival_time_ms - current_timestamp_group_.complete_time_ms;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000148 uint32_t timestamp_diff = timestamp - current_timestamp_group_.timestamp;
149 int64_t ts_delta_ms = timestamp_to_ms_coeff_ * timestamp_diff + 0.5;
150 if (ts_delta_ms == 0)
151 return true;
152 int propagation_delta_ms = arrival_time_delta_ms - ts_delta_ms;
Sebastian Janssonbe20ef72018-09-06 12:32:31 +0200153 if (propagation_delta_ms < 0 &&
154 arrival_time_delta_ms <= kBurstDeltaThresholdMs &&
155 arrival_time_ms - current_timestamp_group_.first_arrival_ms <
156 kMaxBurstDurationMs)
157 return true;
158 return false;
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000159}
stefan5e12d362016-07-11 01:44:02 -0700160
161void InterArrival::Reset() {
162 num_consecutive_reordered_packets_ = 0;
163 current_timestamp_group_ = TimestampGroup();
164 prev_timestamp_group_ = TimestampGroup();
165}
pbos@webrtc.org9f79fe62014-12-04 15:34:06 +0000166} // namespace webrtc