1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CAST_STREAMING_PACKET_RECEIVE_STATS_TRACKER_H_ 6 #define CAST_STREAMING_PACKET_RECEIVE_STATS_TRACKER_H_ 7 8 #include <stdint.h> 9 10 #include "cast/streaming/expanded_value_base.h" 11 #include "cast/streaming/rtcp_common.h" 12 #include "cast/streaming/rtp_time.h" 13 #include "platform/api/time.h" 14 15 namespace openscreen { 16 namespace cast { 17 18 // Maintains statistics for RTP packet arrival timing, jitter, and loss rates; 19 // and then uses these to compute and set the related fields in a RTCP Receiver 20 // Report block. 21 class PacketReceiveStatsTracker { 22 public: 23 explicit PacketReceiveStatsTracker(int rtp_timebase); 24 ~PacketReceiveStatsTracker(); 25 26 // This should be called each time a RTP packet is successfully parsed, 27 // whether the packet is a duplicate or not. The |sequence_number| and 28 // |rtp_timestamp| arguments should be the values from the 29 // RtpPacketParser::ParseResult. |arrival_time| is when the packet was 30 // received (i.e., right-off the network socket, before any 31 // processing/parsing). 32 void OnReceivedValidRtpPacket(uint16_t sequence_number, 33 RtpTimeTicks rtp_timestamp, 34 Clock::time_point arrival_time); 35 36 // Populates *only* those fields in the given |report| that pertain to packet 37 // loss, jitter, and the latest-known RTP packet sequence number. 38 void PopulateNextReport(RtcpReportBlock* report); 39 40 private: 41 // Expands the 16-bit raw packet sequence counter values into full-form, 42 // initially constructed from a "first" value. 43 class PacketSequenceNumber 44 : public ExpandedValueBase<int64_t, PacketSequenceNumber> { 45 public: PacketSequenceNumber()46 constexpr PacketSequenceNumber() 47 : ExpandedValueBase(std::numeric_limits<int64_t>::min()) {} PacketSequenceNumber(uint16_t first_raw_counter_value)48 constexpr explicit PacketSequenceNumber(uint16_t first_raw_counter_value) 49 : ExpandedValueBase(static_cast<int64_t>(first_raw_counter_value)) {} 50 is_null()51 constexpr bool is_null() const { return *this == PacketSequenceNumber(); } 52 previous()53 constexpr PacketSequenceNumber previous() const { 54 return PacketSequenceNumber(value_ - 1); 55 } 56 57 // Distance operator. 58 constexpr int64_t operator-(PacketSequenceNumber rhs) const { 59 return value_ - rhs.value_; 60 } 61 62 private: 63 friend class ExpandedValueBase<int64_t, PacketSequenceNumber>; 64 PacketSequenceNumber(int64_t value)65 constexpr explicit PacketSequenceNumber(int64_t value) 66 : ExpandedValueBase(value) {} 67 }; 68 69 const int rtp_timebase_; // RTP timestamp ticks per second. 70 71 // Until |num_rtp_packets_received_| is greater than zero, the rest of these 72 // fields contain invalid values. 73 int64_t num_rtp_packets_received_ = 0; 74 int64_t num_rtp_packets_received_at_last_report_; 75 76 // The greatest packet sequence number seen in any RTP packet. 77 PacketSequenceNumber greatest_sequence_number_; 78 79 // One before the packet sequence number contained in the very first RTP 80 // packet seen. This is "one before" to simplify the packet count 81 // calculations. 82 PacketSequenceNumber base_sequence_number_; 83 84 // The value of |greatest_sequence_number_| when the last call to 85 // PopulateNextReport() was made. This is used in the computation of the 86 // packet loss rate between reports. 87 PacketSequenceNumber greatest_sequence_number_at_last_report_; 88 89 // The time the last RTP packet was received. This is used in the computation 90 // that updates |jitter_|. 91 Clock::time_point last_rtp_packet_arrival_time_; 92 93 // The RTP timestamp of the last RTP packet received. This is used in the 94 // computation that updates |jitter_|. 95 RtpTimeTicks last_rtp_packet_timestamp_; 96 97 // The interarrival jitter. See RFC 3550 spec, section 6.4.1. The Cast 98 // Streaming spec diverges from the algorithm in the RFC spec in that it uses 99 // different pieces of timing data to calculate this metric. 100 Clock::duration jitter_; 101 }; 102 103 } // namespace cast 104 } // namespace openscreen 105 106 #endif // CAST_STREAMING_PACKET_RECEIVE_STATS_TRACKER_H_ 107