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 <memory>
15 #include <vector>
16 
17 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18 #include "rtc_base/constructormagic.h"
19 #include "rtc_base/criticalsection.h"
20 #include "rtc_base/thread_annotations.h"
21 #include "typedefs.h"  // NOLINT(build/include)
22 
23 namespace webrtc {
24 
25 class Clock;
26 class RtpPacketToSend;
27 
28 class RtpPacketHistory {
29  public:
30   static constexpr size_t kMaxCapacity = 9600;
31   explicit RtpPacketHistory(Clock* clock);
32   ~RtpPacketHistory();
33 
34   void SetStorePacketsStatus(bool enable, uint16_t number_to_store);
35   bool StorePackets() const;
36 
37   void PutRtpPacket(std::unique_ptr<RtpPacketToSend> packet,
38                     StorageType type,
39                     bool sent);
40 
41   // Gets stored RTP packet corresponding to the input |sequence number|.
42   // Returns nullptr if packet is not found.
43   // |min_elapsed_time_ms| is the minimum time that must have elapsed since
44   // the last time the packet was resent (parameter is ignored if set to zero).
45   // If the packet is found but the minimum time has not elapsed, returns
46   // nullptr.
47   std::unique_ptr<RtpPacketToSend> GetPacketAndSetSendTime(
48       uint16_t sequence_number,
49       int64_t min_elapsed_time_ms,
50       bool retransmit);
51 
52   std::unique_ptr<RtpPacketToSend> GetBestFittingPacket(
53       size_t packet_size) const;
54 
55   bool HasRtpPacket(uint16_t sequence_number) const;
56 
57  private:
58   struct StoredPacket {
59     uint16_t sequence_number = 0;
60     int64_t send_time = 0;
61     StorageType storage_type = kDontRetransmit;
62     bool has_been_retransmitted = false;
63 
64     std::unique_ptr<RtpPacketToSend> packet;
65   };
66 
67   std::unique_ptr<RtpPacketToSend> GetPacket(int index) const
68       RTC_EXCLUSIVE_LOCKS_REQUIRED(critsect_);
69   void Allocate(size_t number_to_store) RTC_EXCLUSIVE_LOCKS_REQUIRED(critsect_);
70   void Free() RTC_EXCLUSIVE_LOCKS_REQUIRED(critsect_);
71   bool FindSeqNum(uint16_t sequence_number, int* index) const
72       RTC_EXCLUSIVE_LOCKS_REQUIRED(critsect_);
73   int FindBestFittingPacket(size_t size) const
74       RTC_EXCLUSIVE_LOCKS_REQUIRED(critsect_);
75 
76   Clock* clock_;
77   rtc::CriticalSection critsect_;
78   bool store_ RTC_GUARDED_BY(critsect_);
79   uint32_t prev_index_ RTC_GUARDED_BY(critsect_);
80   std::vector<StoredPacket> stored_packets_ RTC_GUARDED_BY(critsect_);
81 
82   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RtpPacketHistory);
83 };
84 }  // namespace webrtc
85 #endif  // MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_
86