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