Line data Source code
1 : /*
2 : * Copyright (c) 2016 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 : #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
11 : #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
12 :
13 : #include <vector>
14 :
15 : #include "webrtc/base/array_view.h"
16 : #include "webrtc/base/basictypes.h"
17 : #include "webrtc/base/copyonwritebuffer.h"
18 : #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
19 :
20 : namespace webrtc {
21 : struct RTPHeader;
22 : class RtpHeaderExtensionMap;
23 : class Random;
24 :
25 : namespace rtp {
26 : class Packet {
27 : public:
28 : using ExtensionType = RTPExtensionType;
29 : using ExtensionManager = RtpHeaderExtensionMap;
30 : static constexpr size_t kMaxExtensionHeaders = 14;
31 :
32 : // Parse and copy given buffer into Packet.
33 : bool Parse(const uint8_t* buffer, size_t size);
34 : bool Parse(rtc::ArrayView<const uint8_t> packet);
35 :
36 : // Parse and move given buffer into Packet.
37 : bool Parse(rtc::CopyOnWriteBuffer packet);
38 :
39 : // Maps extensions id to their types.
40 : void IdentifyExtensions(const ExtensionManager& extensions);
41 :
42 : // Header.
43 : bool Marker() const;
44 : uint8_t PayloadType() const;
45 : uint16_t SequenceNumber() const;
46 : uint32_t Timestamp() const;
47 : uint32_t Ssrc() const;
48 : std::vector<uint32_t> Csrcs() const;
49 :
50 : // TODO(danilchap): Remove this function when all code update to use RtpPacket
51 : // directly. Function is there just for easier backward compatibilty.
52 : void GetHeader(RTPHeader* header) const;
53 :
54 : size_t headers_size() const;
55 :
56 : // Payload.
57 : size_t payload_size() const;
58 : size_t padding_size() const;
59 : rtc::ArrayView<const uint8_t> payload() const;
60 :
61 : // Buffer.
62 : rtc::CopyOnWriteBuffer Buffer() const;
63 : size_t capacity() const;
64 : size_t size() const;
65 : const uint8_t* data() const;
66 : size_t FreeCapacity() const;
67 : size_t MaxPayloadSize() const;
68 :
69 : // Reset fields and buffer.
70 : void Clear();
71 :
72 : // Header setters.
73 : void CopyHeaderFrom(const Packet& packet);
74 : void SetMarker(bool marker_bit);
75 : void SetPayloadType(uint8_t payload_type);
76 : void SetSequenceNumber(uint16_t seq_no);
77 : void SetTimestamp(uint32_t timestamp);
78 : void SetSsrc(uint32_t ssrc);
79 :
80 : // Writes csrc list. Assumes:
81 : // a) There is enough room left in buffer.
82 : // b) Extension headers, payload or padding data has not already been added.
83 : void SetCsrcs(const std::vector<uint32_t>& csrcs);
84 :
85 : // Header extensions.
86 : template <typename Extension>
87 : bool HasExtension() const;
88 :
89 : template <typename Extension, typename... Values>
90 : bool GetExtension(Values...) const;
91 :
92 : template <typename Extension, typename... Values>
93 : bool SetExtension(Values...);
94 : template <typename Extension, typename... Values>
95 : bool SetExtensionWithLength(size_t length, Values...);
96 :
97 : template <typename Extension>
98 : bool ReserveExtension();
99 :
100 : // Reserve size_bytes for payload. Returns nullptr on failure.
101 : uint8_t* AllocatePayload(size_t size_bytes);
102 : void SetPayloadSize(size_t size_bytes);
103 : bool SetPadding(uint8_t size_bytes, Random* random);
104 :
105 : protected:
106 : // |extensions| required for SetExtension/ReserveExtension functions during
107 : // packet creating and used if available in Parse function.
108 : // Adding and getting extensions will fail until |extensions| is
109 : // provided via constructor or IdentifyExtensions function.
110 : Packet();
111 : explicit Packet(const ExtensionManager* extensions);
112 0 : Packet(const Packet&) = default;
113 : Packet(const ExtensionManager* extensions, size_t capacity);
114 : virtual ~Packet();
115 :
116 : Packet& operator=(const Packet&) = default;
117 :
118 : private:
119 : struct ExtensionInfo {
120 : ExtensionType type;
121 : uint16_t offset;
122 : uint8_t length;
123 : };
124 :
125 : // Helper function for Parse. Fill header fields using data in given buffer,
126 : // but does not touch packet own buffer, leaving packet in invalid state.
127 : bool ParseBuffer(const uint8_t* buffer, size_t size);
128 :
129 : // Find an extension based on the type field of the parameter.
130 : // If found, length field would be validated, the offset field will be set
131 : // and true returned,
132 : // otherwise the parameter will be unchanged and false is returned.
133 : bool FindExtension(ExtensionType type,
134 : uint8_t length,
135 : uint16_t* offset) const;
136 :
137 : // Find or allocate an extension, based on the type field of the parameter.
138 : // If found, the length field be checked against what is already registered
139 : // and the offset field will be set, then true is returned. If allocated, the
140 : // length field will be used for allocation and the offset update to indicate
141 : // position, the true is returned.
142 : // If not found and allocations fails, false is returned and parameter remains
143 : // unchanged.
144 : bool AllocateExtension(ExtensionType type, uint8_t length, uint16_t* offset);
145 :
146 : uint8_t* WriteAt(size_t offset);
147 : void WriteAt(size_t offset, uint8_t byte);
148 :
149 : // Header.
150 : bool marker_;
151 : uint8_t payload_type_;
152 : uint8_t padding_size_;
153 : uint16_t sequence_number_;
154 : uint32_t timestamp_;
155 : uint32_t ssrc_;
156 : size_t payload_offset_; // Match header size with csrcs and extensions.
157 : size_t payload_size_;
158 :
159 : ExtensionInfo extension_entries_[kMaxExtensionHeaders];
160 : uint16_t extensions_size_ = 0; // Unaligned.
161 : rtc::CopyOnWriteBuffer buffer_;
162 : };
163 :
164 : template <typename Extension>
165 : bool Packet::HasExtension() const {
166 : uint16_t offset = 0;
167 : return FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset);
168 : }
169 :
170 : template <typename Extension, typename... Values>
171 0 : bool Packet::GetExtension(Values... values) const {
172 0 : uint16_t offset = 0;
173 0 : if (!FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
174 0 : return false;
175 0 : return Extension::Parse(data() + offset, values...);
176 : }
177 :
178 : template <typename Extension, typename... Values>
179 0 : bool Packet::SetExtension(Values... values) {
180 0 : uint16_t offset = 0;
181 0 : if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
182 0 : return false;
183 0 : return Extension::Write(WriteAt(offset), values...);
184 : }
185 :
186 : template <typename Extension, typename... Values>
187 0 : bool Packet::SetExtensionWithLength(size_t length, Values... values) {
188 0 : uint16_t offset = 0;
189 0 : if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes + length, &offset))
190 0 : return false;
191 0 : return Extension::Write(WriteAt(offset), values...);
192 : }
193 :
194 : template <typename Extension>
195 0 : bool Packet::ReserveExtension() {
196 0 : uint16_t offset = 0;
197 0 : if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
198 0 : return false;
199 0 : memset(WriteAt(offset), 0, Extension::kValueSizeBytes);
200 0 : return true;
201 : }
202 : } // namespace rtp
203 : } // namespace webrtc
204 :
205 : #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
|