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