mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
139 lines
5.5 KiB
C++
139 lines
5.5 KiB
C++
/*
|
|
* Copyright (c) 2020 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 "inter_arrival_delta.h"
|
|
|
|
#include <algorithm>
|
|
#include <cstddef>
|
|
|
|
#include "api/units/time_delta.h"
|
|
#include "api/units/timestamp.h"
|
|
#include "log.h"
|
|
|
|
namespace webrtc {
|
|
|
|
static constexpr TimeDelta kBurstDeltaThreshold = TimeDelta::Millis(5);
|
|
static constexpr TimeDelta kMaxBurstDuration = TimeDelta::Millis(100);
|
|
constexpr TimeDelta InterArrivalDelta::kArrivalTimeOffsetThreshold;
|
|
|
|
InterArrivalDelta::InterArrivalDelta(TimeDelta send_time_group_length)
|
|
: send_time_group_length_(send_time_group_length),
|
|
current_timestamp_group_(),
|
|
prev_timestamp_group_(),
|
|
num_consecutive_reordered_packets_(0) {}
|
|
|
|
bool InterArrivalDelta::ComputeDeltas(Timestamp send_time,
|
|
Timestamp arrival_time,
|
|
Timestamp system_time, size_t packet_size,
|
|
TimeDelta* send_time_delta,
|
|
TimeDelta* arrival_time_delta,
|
|
int* 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_.send_time = send_time;
|
|
current_timestamp_group_.first_send_time = send_time;
|
|
current_timestamp_group_.first_arrival = arrival_time;
|
|
} else if (current_timestamp_group_.first_send_time > send_time) {
|
|
// Reordered packet.
|
|
return false;
|
|
} else if (NewTimestampGroup(arrival_time, send_time)) {
|
|
// First packet of a later send burst, the previous packets sample is ready.
|
|
if (prev_timestamp_group_.complete_time.IsFinite()) {
|
|
*send_time_delta =
|
|
current_timestamp_group_.send_time - prev_timestamp_group_.send_time;
|
|
*arrival_time_delta = current_timestamp_group_.complete_time -
|
|
prev_timestamp_group_.complete_time;
|
|
|
|
TimeDelta system_time_delta = current_timestamp_group_.last_system_time -
|
|
prev_timestamp_group_.last_system_time;
|
|
|
|
if (*arrival_time_delta - system_time_delta >=
|
|
kArrivalTimeOffsetThreshold) {
|
|
LOG_WARN(
|
|
"The arrival time clock offset has changed (diff = {} ms), "
|
|
"resetting.",
|
|
arrival_time_delta->ms() - system_time_delta.ms());
|
|
Reset();
|
|
return false;
|
|
}
|
|
if (*arrival_time_delta < TimeDelta::Zero()) {
|
|
// The group of packets has been reordered since receiving its local
|
|
// arrival timestamp.
|
|
++num_consecutive_reordered_packets_;
|
|
if (num_consecutive_reordered_packets_ >= kReorderedResetThreshold) {
|
|
LOG_WARN(
|
|
"Packets between send burst arrived out of order, resetting: "
|
|
"arrival_time_delta_ms={}, send_time_delta_ms={}",
|
|
arrival_time_delta->ms(), send_time_delta->ms());
|
|
Reset();
|
|
}
|
|
return false;
|
|
} else {
|
|
num_consecutive_reordered_packets_ = 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_send_time = send_time;
|
|
current_timestamp_group_.send_time = send_time;
|
|
current_timestamp_group_.first_arrival = arrival_time;
|
|
current_timestamp_group_.size = 0;
|
|
} else {
|
|
current_timestamp_group_.send_time =
|
|
std::max(current_timestamp_group_.send_time, send_time);
|
|
}
|
|
// Accumulate the frame size.
|
|
current_timestamp_group_.size += packet_size;
|
|
current_timestamp_group_.complete_time = arrival_time;
|
|
current_timestamp_group_.last_system_time = system_time;
|
|
|
|
return calculated_deltas;
|
|
}
|
|
|
|
// Assumes that `timestamp` is not reordered compared to
|
|
// `current_timestamp_group_`.
|
|
bool InterArrivalDelta::NewTimestampGroup(Timestamp arrival_time,
|
|
Timestamp send_time) const {
|
|
if (current_timestamp_group_.IsFirstPacket()) {
|
|
return false;
|
|
} else if (BelongsToBurst(arrival_time, send_time)) {
|
|
return false;
|
|
} else {
|
|
return send_time - current_timestamp_group_.first_send_time >
|
|
send_time_group_length_;
|
|
}
|
|
}
|
|
|
|
bool InterArrivalDelta::BelongsToBurst(Timestamp arrival_time,
|
|
Timestamp send_time) const {
|
|
TimeDelta arrival_time_delta =
|
|
arrival_time - current_timestamp_group_.complete_time;
|
|
TimeDelta send_time_delta = send_time - current_timestamp_group_.send_time;
|
|
if (send_time_delta.IsZero()) return true;
|
|
TimeDelta propagation_delta = arrival_time_delta - send_time_delta;
|
|
if (propagation_delta < TimeDelta::Zero() &&
|
|
arrival_time_delta <= kBurstDeltaThreshold &&
|
|
arrival_time - current_timestamp_group_.first_arrival < kMaxBurstDuration)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void InterArrivalDelta::Reset() {
|
|
num_consecutive_reordered_packets_ = 0;
|
|
current_timestamp_group_ = SendTimeGroup();
|
|
prev_timestamp_group_ = SendTimeGroup();
|
|
}
|
|
} // namespace webrtc
|