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 *  Class for storing RTP packets.
11 */
12
13#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_
14#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_
15
16#include <vector>
17
18#include "webrtc/base/thread_annotations.h"
19#include "webrtc/modules/include/module_common_types.h"
20#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
21#include "webrtc/typedefs.h"
22
23namespace webrtc {
24
25class Clock;
26class CriticalSectionWrapper;
27
28static const size_t kMaxHistoryCapacity = 9600;
29
30class RTPPacketHistory {
31 public:
32  explicit RTPPacketHistory(Clock* clock);
33  ~RTPPacketHistory();
34
35  void SetStorePacketsStatus(bool enable, uint16_t number_to_store);
36
37  bool StorePackets() const;
38
39  // Stores RTP packet.
40  int32_t PutRTPPacket(const uint8_t* packet,
41                       size_t packet_length,
42                       int64_t capture_time_ms,
43                       StorageType type);
44
45  // Gets stored RTP packet corresponding to the input sequence number.
46  // The packet is copied to the buffer pointed to by ptr_rtp_packet.
47  // The rtp_packet_length should show the available buffer size.
48  // Returns true if packet is found.
49  // packet_length: returns the copied packet length on success.
50  // min_elapsed_time_ms: the minimum time that must have elapsed since the last
51  // time the packet was resent (parameter is ignored if set to zero).
52  // If the packet is found but the minimum time has not elapsed, no bytes are
53  // copied.
54  // stored_time_ms: returns the time when the packet was stored.
55  bool GetPacketAndSetSendTime(uint16_t sequence_number,
56                               int64_t min_elapsed_time_ms,
57                               bool retransmit,
58                               uint8_t* packet,
59                               size_t* packet_length,
60                               int64_t* stored_time_ms);
61
62  bool GetBestFittingPacket(uint8_t* packet, size_t* packet_length,
63                            int64_t* stored_time_ms);
64
65  bool HasRTPPacket(uint16_t sequence_number) const;
66
67  bool SetSent(uint16_t sequence_number);
68
69 private:
70  void GetPacket(int index,
71                 uint8_t* packet,
72                 size_t* packet_length,
73                 int64_t* stored_time_ms) const
74      EXCLUSIVE_LOCKS_REQUIRED(*critsect_);
75  void Allocate(size_t number_to_store) EXCLUSIVE_LOCKS_REQUIRED(*critsect_);
76  void Free() EXCLUSIVE_LOCKS_REQUIRED(*critsect_);
77  void VerifyAndAllocatePacketLength(size_t packet_length, uint32_t start_index)
78      EXCLUSIVE_LOCKS_REQUIRED(*critsect_);
79  bool FindSeqNum(uint16_t sequence_number, int32_t* index) const
80      EXCLUSIVE_LOCKS_REQUIRED(*critsect_);
81  int FindBestFittingPacket(size_t size) const
82      EXCLUSIVE_LOCKS_REQUIRED(*critsect_);
83
84 private:
85  Clock* clock_;
86  rtc::scoped_ptr<CriticalSectionWrapper> critsect_;
87  bool store_ GUARDED_BY(critsect_);
88  uint32_t prev_index_ GUARDED_BY(critsect_);
89
90  struct StoredPacket {
91    StoredPacket();
92    uint16_t sequence_number = 0;
93    int64_t time_ms = 0;
94    int64_t send_time = 0;
95    StorageType storage_type = kDontRetransmit;
96    bool has_been_retransmitted = false;
97
98    uint8_t data[IP_PACKET_SIZE];
99    size_t length = 0;
100  };
101  std::vector<StoredPacket> stored_packets_ GUARDED_BY(critsect_);
102};
103}  // namespace webrtc
104#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_HISTORY_H_
105