You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.9 KiB
80 lines
2.9 KiB
// Copyright 2019 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "cast/streaming/packet_receive_stats_tracker.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace openscreen {
|
|
namespace cast {
|
|
|
|
PacketReceiveStatsTracker::PacketReceiveStatsTracker(int rtp_timebase)
|
|
: rtp_timebase_(rtp_timebase) {}
|
|
|
|
PacketReceiveStatsTracker::~PacketReceiveStatsTracker() = default;
|
|
|
|
void PacketReceiveStatsTracker::OnReceivedValidRtpPacket(
|
|
uint16_t sequence_number,
|
|
RtpTimeTicks rtp_timestamp,
|
|
Clock::time_point arrival_time) {
|
|
if (num_rtp_packets_received_ == 0) {
|
|
// Since this is the very first packet received, initialize all other
|
|
// tracking stats.
|
|
num_rtp_packets_received_at_last_report_ = 0;
|
|
greatest_sequence_number_ = PacketSequenceNumber(sequence_number);
|
|
base_sequence_number_ = greatest_sequence_number_.previous();
|
|
greatest_sequence_number_at_last_report_ = base_sequence_number_;
|
|
jitter_ = Clock::duration::zero();
|
|
} else {
|
|
// Update the greatest sequence number ever seen.
|
|
const auto expanded_sequence_number =
|
|
greatest_sequence_number_.Expand(sequence_number);
|
|
if (expanded_sequence_number > greatest_sequence_number_) {
|
|
greatest_sequence_number_ = expanded_sequence_number;
|
|
}
|
|
|
|
// Update the interarrival jitter. This is similar to the calculation in
|
|
// Appendix A of the RFC 3550 spec (for RTP).
|
|
const Clock::duration time_between_arrivals =
|
|
arrival_time - last_rtp_packet_arrival_time_;
|
|
const auto media_time_difference =
|
|
(rtp_timestamp - last_rtp_packet_timestamp_)
|
|
.ToDuration<Clock::duration>(rtp_timebase_);
|
|
const auto delta = time_between_arrivals - media_time_difference;
|
|
const auto absolute_delta =
|
|
(delta < decltype(delta)::zero()) ? -delta : delta;
|
|
jitter_ += (absolute_delta - jitter_) / 16;
|
|
}
|
|
|
|
++num_rtp_packets_received_;
|
|
last_rtp_packet_arrival_time_ = arrival_time;
|
|
last_rtp_packet_timestamp_ = rtp_timestamp;
|
|
}
|
|
|
|
void PacketReceiveStatsTracker::PopulateNextReport(RtcpReportBlock* report) {
|
|
if (num_rtp_packets_received_ <= 0) {
|
|
// None of the packet loss, etc., tracking has valid values yet; so don't
|
|
// populate anything.
|
|
return;
|
|
}
|
|
|
|
report->SetPacketFractionLostNumerator(
|
|
greatest_sequence_number_ - greatest_sequence_number_at_last_report_,
|
|
num_rtp_packets_received_ - num_rtp_packets_received_at_last_report_);
|
|
greatest_sequence_number_at_last_report_ = greatest_sequence_number_;
|
|
num_rtp_packets_received_at_last_report_ = num_rtp_packets_received_;
|
|
|
|
report->SetCumulativePacketsLost(
|
|
greatest_sequence_number_ - base_sequence_number_,
|
|
num_rtp_packets_received_);
|
|
|
|
report->extended_high_sequence_number =
|
|
greatest_sequence_number_.lower_32_bits();
|
|
|
|
report->jitter = RtpTimeDelta::FromDuration(jitter_, rtp_timebase_);
|
|
}
|
|
|
|
} // namespace cast
|
|
} // namespace openscreen
|