rtp_packet_history.h (8047B)
1 /* 2 * Copyright (c) 2012 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_RTP_PACKET_HISTORY_H_ 12 #define MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_ 13 14 #include <cstddef> 15 #include <cstdint> 16 #include <deque> 17 #include <memory> 18 #include <optional> 19 20 #include "api/array_view.h" 21 #include "api/environment/environment.h" 22 #include "api/function_view.h" 23 #include "api/units/time_delta.h" 24 #include "api/units/timestamp.h" 25 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 26 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" 27 #include "rtc_base/synchronization/mutex.h" 28 #include "rtc_base/thread_annotations.h" 29 30 namespace webrtc { 31 32 class Clock; 33 34 class RtpPacketHistory { 35 public: 36 enum class StorageMode { 37 kDisabled, // Don't store any packets. 38 kStoreAndCull // Store up to `number_to_store` packets, but try to remove 39 // packets as they time out or as signaled as received. 40 }; 41 42 enum class PaddingMode { 43 kDefault, // Last packet stored in the history that has not yet been 44 // culled. 45 kRecentLargePacket // Use the most recent large packet. Packet is kept for 46 // padding even after it has been culled from history. 47 }; 48 49 // Maximum number of packets we ever allow in the history. 50 static constexpr size_t kMaxCapacity = 9600; 51 // Maximum number of entries in prioritized queue of padding packets. 52 static constexpr size_t kMaxPaddingHistory = 63; 53 // Don't remove packets within max(1 second, 3x RTT). 54 static constexpr TimeDelta kMinPacketDuration = TimeDelta::Seconds(1); 55 static constexpr int kMinPacketDurationRtt = 3; 56 // With kStoreAndCull, always remove packets after 3x max(1000ms, 3x rtt). 57 static constexpr int kPacketCullingDelayFactor = 3; 58 59 RtpPacketHistory(const Environment& env, PaddingMode padding_mode); 60 61 RtpPacketHistory() = delete; 62 RtpPacketHistory(const RtpPacketHistory&) = delete; 63 RtpPacketHistory& operator=(const RtpPacketHistory&) = delete; 64 65 ~RtpPacketHistory(); 66 67 // Set/get storage mode. Note that setting the state will clear the history, 68 // even if setting the same state as is currently used. 69 void SetStorePacketsStatus(StorageMode mode, size_t number_to_store); 70 StorageMode GetStorageMode() const; 71 72 // Set RTT, used to avoid premature retransmission and to prevent over-writing 73 // a packet in the history before we are reasonably sure it has been received. 74 void SetRtt(TimeDelta rtt); 75 76 void PutRtpPacket(std::unique_ptr<RtpPacketToSend> packet, 77 Timestamp send_time); 78 79 // Gets stored RTP packet corresponding to the input |sequence number|. 80 // Returns nullptr if packet is not found or was (re)sent too recently. 81 // If a packet copy is returned, it will be marked as pending transmission but 82 // does not update send time, that must be done by MarkPacketAsSent(). 83 std::unique_ptr<RtpPacketToSend> GetPacketAndMarkAsPending( 84 uint16_t sequence_number); 85 86 // In addition to getting packet and marking as sent, this method takes an 87 // encapsulator function that takes a reference to the packet and outputs a 88 // copy that may be wrapped in a container, eg RTX. 89 // If the the encapsulator returns nullptr, the retransmit is aborted and the 90 // packet will not be marked as pending. 91 std::unique_ptr<RtpPacketToSend> GetPacketAndMarkAsPending( 92 uint16_t sequence_number, 93 FunctionView<std::unique_ptr<RtpPacketToSend>(const RtpPacketToSend&)> 94 encapsulate); 95 96 // Updates the send time for the given packet and increments the transmission 97 // counter. Marks the packet as no longer being in the pacer queue. 98 void MarkPacketAsSent(uint16_t sequence_number); 99 100 // Returns true if history contains packet with `sequence_number` and it can 101 // be retransmitted. 102 bool GetPacketState(uint16_t sequence_number) const; 103 104 // Get the packet (if any) from the history, that is deemed most likely to 105 // the remote side. This is calculated from heuristics such as packet age 106 // and times retransmitted. Updated the send time of the packet, so is not 107 // a const method. 108 std::unique_ptr<RtpPacketToSend> GetPayloadPaddingPacket(); 109 110 // Same as GetPayloadPaddingPacket(void), but adds an encapsulation 111 // that can be used for instance to encapsulate the packet in an RTX 112 // container, or to abort getting the packet if the function returns 113 // nullptr. 114 std::unique_ptr<RtpPacketToSend> GetPayloadPaddingPacket( 115 FunctionView<std::unique_ptr<RtpPacketToSend>(const RtpPacketToSend&)> 116 encapsulate); 117 118 // Cull packets that have been acknowledged as received by the remote end. 119 void CullAcknowledgedPackets(ArrayView<const uint16_t> sequence_numbers); 120 121 // Remove all pending packets from the history, but keep storage mode and 122 // capacity. 123 void Clear(); 124 125 private: 126 class StoredPacket { 127 public: 128 StoredPacket() = default; 129 StoredPacket(std::unique_ptr<RtpPacketToSend> packet, 130 Timestamp send_time, 131 uint64_t insert_order); 132 StoredPacket(StoredPacket&&); 133 StoredPacket& operator=(StoredPacket&&); 134 ~StoredPacket(); 135 136 uint64_t insert_order() const { return insert_order_; } 137 size_t times_retransmitted() const { return times_retransmitted_; } 138 void IncrementTimesRetransmitted(); 139 140 // The time of last transmission, including retransmissions. 141 Timestamp send_time() const { return send_time_; } 142 void set_send_time(Timestamp value) { send_time_ = value; } 143 144 // The actual packet. 145 std::unique_ptr<RtpPacketToSend> packet_; 146 147 // True if the packet is currently in the pacer queue pending transmission. 148 bool pending_transmission_; 149 150 private: 151 Timestamp send_time_ = Timestamp::Zero(); 152 153 // Unique number per StoredPacket, incremented by one for each added 154 // packet. Used to sort on insert order. 155 uint64_t insert_order_; 156 157 // Number of times RE-transmitted, ie excluding the first transmission. 158 size_t times_retransmitted_; 159 }; 160 161 // Helper method to check if packet has too recently been sent. 162 bool VerifyRtt(const StoredPacket& packet) const 163 RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); 164 void Reset() RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); 165 void CullOldPackets() RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); 166 // Removes the packet from the history, and context/mapping that has been 167 // stored. Returns the RTP packet instance contained within the StoredPacket. 168 std::unique_ptr<RtpPacketToSend> RemovePacket(int packet_index) 169 RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); 170 int GetPacketIndex(uint16_t sequence_number) const 171 RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); 172 StoredPacket* GetStoredPacket(uint16_t sequence_number) 173 RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); 174 175 Clock* const clock_; 176 const PaddingMode padding_mode_; 177 mutable Mutex lock_; 178 size_t number_to_store_ RTC_GUARDED_BY(lock_); 179 StorageMode mode_ RTC_GUARDED_BY(lock_); 180 TimeDelta rtt_ RTC_GUARDED_BY(lock_); 181 182 // Queue of stored packets, ordered by sequence number, with older packets in 183 // the front and new packets being added to the back. Note that there may be 184 // wrap-arounds so the back may have a lower sequence number. 185 // Packets may also be removed out-of-order, in which case there will be 186 // instances of StoredPacket with `packet_` set to nullptr. The first and last 187 // entry in the queue will however always be populated. 188 std::deque<StoredPacket> packet_history_ RTC_GUARDED_BY(lock_); 189 190 // Total number of packets with inserted. 191 uint64_t packets_inserted_ RTC_GUARDED_BY(lock_); 192 193 std::optional<RtpPacketToSend> large_payload_packet_ RTC_GUARDED_BY(lock_); 194 }; 195 } // namespace webrtc 196 #endif // MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_