• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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