1 /*
2  *  Copyright (c) 2019 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_SOURCE_TRACKER_H_
12 #define MODULES_RTP_RTCP_SOURCE_SOURCE_TRACKER_H_
13 
14 #include <cstdint>
15 #include <list>
16 #include <unordered_map>
17 #include <utility>
18 #include <vector>
19 
20 #include "absl/types/optional.h"
21 #include "api/rtp_packet_infos.h"
22 #include "api/transport/rtp/rtp_source.h"
23 #include "rtc_base/synchronization/mutex.h"
24 #include "rtc_base/time_utils.h"
25 #include "system_wrappers/include/clock.h"
26 
27 namespace webrtc {
28 
29 //
30 // Tracker for `RTCRtpContributingSource` and `RTCRtpSynchronizationSource`:
31 //   - https://w3c.github.io/webrtc-pc/#dom-rtcrtpcontributingsource
32 //   - https://w3c.github.io/webrtc-pc/#dom-rtcrtpsynchronizationsource
33 //
34 class SourceTracker {
35  public:
36   // Amount of time before the entry associated with an update is removed. See:
37   // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources
38   static constexpr int64_t kTimeoutMs = 10000;  // 10 seconds
39 
40   explicit SourceTracker(Clock* clock);
41 
42   SourceTracker(const SourceTracker& other) = delete;
43   SourceTracker(SourceTracker&& other) = delete;
44   SourceTracker& operator=(const SourceTracker& other) = delete;
45   SourceTracker& operator=(SourceTracker&& other) = delete;
46 
47   // Updates the source entries when a frame is delivered to the
48   // RTCRtpReceiver's MediaStreamTrack.
49   void OnFrameDelivered(const RtpPacketInfos& packet_infos);
50 
51   // Returns an |RtpSource| for each unique SSRC and CSRC identifier updated in
52   // the last |kTimeoutMs| milliseconds. Entries appear in reverse chronological
53   // order (i.e. with the most recently updated entries appearing first).
54   std::vector<RtpSource> GetSources() const;
55 
56  private:
57   struct SourceKey {
SourceKeySourceKey58     SourceKey(RtpSourceType source_type, uint32_t source)
59         : source_type(source_type), source(source) {}
60 
61     // Type of |source|.
62     RtpSourceType source_type;
63 
64     // CSRC or SSRC identifier of the contributing or synchronization source.
65     uint32_t source;
66   };
67 
68   struct SourceKeyComparator {
operatorSourceKeyComparator69     bool operator()(const SourceKey& lhs, const SourceKey& rhs) const {
70       return (lhs.source_type == rhs.source_type) && (lhs.source == rhs.source);
71     }
72   };
73 
74   struct SourceKeyHasher {
operatorSourceKeyHasher75     size_t operator()(const SourceKey& value) const {
76       return static_cast<size_t>(value.source_type) +
77              static_cast<size_t>(value.source) * 11076425802534262905ULL;
78     }
79   };
80 
81   struct SourceEntry {
82     // Timestamp indicating the most recent time a frame from an RTP packet,
83     // originating from this source, was delivered to the RTCRtpReceiver's
84     // MediaStreamTrack. Its reference clock is the outer class's |clock_|.
85     int64_t timestamp_ms;
86 
87     // Audio level from an RFC 6464 or RFC 6465 header extension received with
88     // the most recent packet used to assemble the frame associated with
89     // |timestamp_ms|. May be absent. Only relevant for audio receivers. See the
90     // specs for `RTCRtpContributingSource` for more info.
91     absl::optional<uint8_t> audio_level;
92 
93     // Absolute capture time header extension received or interpolated from the
94     // most recent packet used to assemble the frame. For more info see
95     // https://webrtc.org/experiments/rtp-hdrext/abs-capture-time/
96     absl::optional<AbsoluteCaptureTime> absolute_capture_time;
97 
98     // RTP timestamp of the most recent packet used to assemble the frame
99     // associated with |timestamp_ms|.
100     uint32_t rtp_timestamp;
101   };
102 
103   using SourceList = std::list<std::pair<const SourceKey, SourceEntry>>;
104   using SourceMap = std::unordered_map<SourceKey,
105                                        SourceList::iterator,
106                                        SourceKeyHasher,
107                                        SourceKeyComparator>;
108 
109   // Updates an entry by creating it (if it didn't previously exist) and moving
110   // it to the front of the list. Returns a reference to the entry.
111   SourceEntry& UpdateEntry(const SourceKey& key)
112       RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_);
113 
114   // Removes entries that have timed out. Marked as "const" so that we can do
115   // pruning in getters.
116   void PruneEntries(int64_t now_ms) const RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_);
117 
118   Clock* const clock_;
119   mutable Mutex lock_;
120 
121   // Entries are stored in reverse chronological order (i.e. with the most
122   // recently updated entries appearing first). Mutability is needed for timeout
123   // pruning in const functions.
124   mutable SourceList list_ RTC_GUARDED_BY(lock_);
125   mutable SourceMap map_ RTC_GUARDED_BY(lock_);
126 };
127 
128 }  // namespace webrtc
129 
130 #endif  // MODULES_RTP_RTCP_SOURCE_SOURCE_TRACKER_H_
131