1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
12 #define MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
13 
14 #include <algorithm>
15 #include <map>
16 #include <vector>
17 
18 #include "absl/types/optional.h"
19 #include "modules/include/module_common_types_public.h"
20 #include "modules/rtp_rtcp/include/receive_statistics.h"
21 #include "rtc_base/rate_statistics.h"
22 #include "rtc_base/synchronization/mutex.h"
23 #include "rtc_base/thread_annotations.h"
24 
25 namespace webrtc {
26 
27 class StreamStatisticianImpl : public StreamStatistician {
28  public:
29   StreamStatisticianImpl(uint32_t ssrc,
30                          Clock* clock,
31                          int max_reordering_threshold);
32   ~StreamStatisticianImpl() override;
33 
34   RtpReceiveStats GetStats() const override;
35 
36   bool GetActiveStatisticsAndReset(RtcpStatistics* statistics);
37   absl::optional<int> GetFractionLostInPercent() const override;
38   StreamDataCounters GetReceiveStreamDataCounters() const override;
39   uint32_t BitrateReceived() const override;
40 
41   void SetMaxReorderingThreshold(int max_reordering_threshold);
42   void EnableRetransmitDetection(bool enable);
43 
44   // Updates StreamStatistician for incoming packets.
45   void UpdateCounters(const RtpPacketReceived& packet);
46 
47  private:
48   bool IsRetransmitOfOldPacket(const RtpPacketReceived& packet,
49                                int64_t now_ms) const
50       RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
51   RtcpStatistics CalculateRtcpStatistics()
52       RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
53   void UpdateJitter(const RtpPacketReceived& packet, int64_t receive_time_ms)
54       RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
55   // Updates StreamStatistician for out of order packets.
56   // Returns true if packet considered to be out of order.
57   bool UpdateOutOfOrder(const RtpPacketReceived& packet,
58                         int64_t sequence_number,
59                         int64_t now_ms)
60       RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
61   // Checks if this StreamStatistician received any rtp packets.
ReceivedRtpPacket()62   bool ReceivedRtpPacket() const RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_) {
63     return received_seq_first_ >= 0;
64   }
65 
66   const uint32_t ssrc_;
67   Clock* const clock_;
68   mutable Mutex stream_lock_;
69   RateStatistics incoming_bitrate_ RTC_GUARDED_BY(&stream_lock_);
70   // In number of packets or sequence numbers.
71   int max_reordering_threshold_ RTC_GUARDED_BY(&stream_lock_);
72   bool enable_retransmit_detection_ RTC_GUARDED_BY(&stream_lock_);
73 
74   // Stats on received RTP packets.
75   uint32_t jitter_q4_ RTC_GUARDED_BY(&stream_lock_);
76   // Cumulative loss according to RFC 3550, which may be negative (and often is,
77   // if packets are reordered and there are non-RTX retransmissions).
78   int32_t cumulative_loss_ RTC_GUARDED_BY(&stream_lock_);
79   // Offset added to outgoing rtcp reports, to make ensure that the reported
80   // cumulative loss is non-negative. Reports with negative values confuse some
81   // senders, in particular, our own loss-based bandwidth estimator.
82   int32_t cumulative_loss_rtcp_offset_ RTC_GUARDED_BY(&stream_lock_);
83 
84   int64_t last_receive_time_ms_ RTC_GUARDED_BY(&stream_lock_);
85   uint32_t last_received_timestamp_ RTC_GUARDED_BY(&stream_lock_);
86   SequenceNumberUnwrapper seq_unwrapper_ RTC_GUARDED_BY(&stream_lock_);
87   int64_t received_seq_first_ RTC_GUARDED_BY(&stream_lock_);
88   int64_t received_seq_max_ RTC_GUARDED_BY(&stream_lock_);
89   // Assume that the other side restarted when there are two sequential packets
90   // with large jump from received_seq_max_.
91   absl::optional<uint16_t> received_seq_out_of_order_
92       RTC_GUARDED_BY(&stream_lock_);
93 
94   // Current counter values.
95   StreamDataCounters receive_counters_ RTC_GUARDED_BY(&stream_lock_);
96 
97   // Counter values when we sent the last report.
98   int32_t last_report_cumulative_loss_ RTC_GUARDED_BY(&stream_lock_);
99   int64_t last_report_seq_max_ RTC_GUARDED_BY(&stream_lock_);
100 };
101 
102 class ReceiveStatisticsImpl : public ReceiveStatistics {
103  public:
104   explicit ReceiveStatisticsImpl(Clock* clock);
105 
106   ~ReceiveStatisticsImpl() override;
107 
108   // Implements ReceiveStatisticsProvider.
109   std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override;
110 
111   // Implements RtpPacketSinkInterface
112   void OnRtpPacket(const RtpPacketReceived& packet) override;
113 
114   // Implements ReceiveStatistics.
115   // Note: More specific return type for use in the implementation.
116   StreamStatisticianImpl* GetStatistician(uint32_t ssrc) const override;
117   void SetMaxReorderingThreshold(int max_reordering_threshold) override;
118   void SetMaxReorderingThreshold(uint32_t ssrc,
119                                  int max_reordering_threshold) override;
120   void EnableRetransmitDetection(uint32_t ssrc, bool enable) override;
121 
122  private:
123   StreamStatisticianImpl* GetOrCreateStatistician(uint32_t ssrc);
124 
125   Clock* const clock_;
126   mutable Mutex receive_statistics_lock_;
127   uint32_t last_returned_ssrc_;
128   int max_reordering_threshold_ RTC_GUARDED_BY(receive_statistics_lock_);
129   std::map<uint32_t, StreamStatisticianImpl*> statisticians_
130       RTC_GUARDED_BY(receive_statistics_lock_);
131 };
132 }  // namespace webrtc
133 #endif  // MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
134