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.
107 lines
4.0 KiB
107 lines
4.0 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.
|
|
|
|
#ifndef CAST_STREAMING_PACKET_RECEIVE_STATS_TRACKER_H_
|
|
#define CAST_STREAMING_PACKET_RECEIVE_STATS_TRACKER_H_
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "cast/streaming/expanded_value_base.h"
|
|
#include "cast/streaming/rtcp_common.h"
|
|
#include "cast/streaming/rtp_time.h"
|
|
#include "platform/api/time.h"
|
|
|
|
namespace openscreen {
|
|
namespace cast {
|
|
|
|
// Maintains statistics for RTP packet arrival timing, jitter, and loss rates;
|
|
// and then uses these to compute and set the related fields in a RTCP Receiver
|
|
// Report block.
|
|
class PacketReceiveStatsTracker {
|
|
public:
|
|
explicit PacketReceiveStatsTracker(int rtp_timebase);
|
|
~PacketReceiveStatsTracker();
|
|
|
|
// This should be called each time a RTP packet is successfully parsed,
|
|
// whether the packet is a duplicate or not. The |sequence_number| and
|
|
// |rtp_timestamp| arguments should be the values from the
|
|
// RtpPacketParser::ParseResult. |arrival_time| is when the packet was
|
|
// received (i.e., right-off the network socket, before any
|
|
// processing/parsing).
|
|
void OnReceivedValidRtpPacket(uint16_t sequence_number,
|
|
RtpTimeTicks rtp_timestamp,
|
|
Clock::time_point arrival_time);
|
|
|
|
// Populates *only* those fields in the given |report| that pertain to packet
|
|
// loss, jitter, and the latest-known RTP packet sequence number.
|
|
void PopulateNextReport(RtcpReportBlock* report);
|
|
|
|
private:
|
|
// Expands the 16-bit raw packet sequence counter values into full-form,
|
|
// initially constructed from a "first" value.
|
|
class PacketSequenceNumber
|
|
: public ExpandedValueBase<int64_t, PacketSequenceNumber> {
|
|
public:
|
|
constexpr PacketSequenceNumber()
|
|
: ExpandedValueBase(std::numeric_limits<int64_t>::min()) {}
|
|
constexpr explicit PacketSequenceNumber(uint16_t first_raw_counter_value)
|
|
: ExpandedValueBase(static_cast<int64_t>(first_raw_counter_value)) {}
|
|
|
|
constexpr bool is_null() const { return *this == PacketSequenceNumber(); }
|
|
|
|
constexpr PacketSequenceNumber previous() const {
|
|
return PacketSequenceNumber(value_ - 1);
|
|
}
|
|
|
|
// Distance operator.
|
|
constexpr int64_t operator-(PacketSequenceNumber rhs) const {
|
|
return value_ - rhs.value_;
|
|
}
|
|
|
|
private:
|
|
friend class ExpandedValueBase<int64_t, PacketSequenceNumber>;
|
|
|
|
constexpr explicit PacketSequenceNumber(int64_t value)
|
|
: ExpandedValueBase(value) {}
|
|
};
|
|
|
|
const int rtp_timebase_; // RTP timestamp ticks per second.
|
|
|
|
// Until |num_rtp_packets_received_| is greater than zero, the rest of these
|
|
// fields contain invalid values.
|
|
int64_t num_rtp_packets_received_ = 0;
|
|
int64_t num_rtp_packets_received_at_last_report_;
|
|
|
|
// The greatest packet sequence number seen in any RTP packet.
|
|
PacketSequenceNumber greatest_sequence_number_;
|
|
|
|
// One before the packet sequence number contained in the very first RTP
|
|
// packet seen. This is "one before" to simplify the packet count
|
|
// calculations.
|
|
PacketSequenceNumber base_sequence_number_;
|
|
|
|
// The value of |greatest_sequence_number_| when the last call to
|
|
// PopulateNextReport() was made. This is used in the computation of the
|
|
// packet loss rate between reports.
|
|
PacketSequenceNumber greatest_sequence_number_at_last_report_;
|
|
|
|
// The time the last RTP packet was received. This is used in the computation
|
|
// that updates |jitter_|.
|
|
Clock::time_point last_rtp_packet_arrival_time_;
|
|
|
|
// The RTP timestamp of the last RTP packet received. This is used in the
|
|
// computation that updates |jitter_|.
|
|
RtpTimeTicks last_rtp_packet_timestamp_;
|
|
|
|
// The interarrival jitter. See RFC 3550 spec, section 6.4.1. The Cast
|
|
// Streaming spec diverges from the algorithm in the RFC spec in that it uses
|
|
// different pieces of timing data to calculate this metric.
|
|
Clock::duration jitter_;
|
|
};
|
|
|
|
} // namespace cast
|
|
} // namespace openscreen
|
|
|
|
#endif // CAST_STREAMING_PACKET_RECEIVE_STATS_TRACKER_H_
|