blob: c00af536de36d7f63d1abc0f93f1d01e4a312f51 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
// 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>
using openscreen::Clock;
namespace cast {
namespace streaming {
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 streaming
} // namespace cast
|