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