tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_