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