blob: b2687ca9babae03ab437fd14b6af89df650fd0a4 [file] [log] [blame]
danilchap1edb7ab2016-04-20 05:25:10 -07001/*
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/basictypes.h"
16#include "webrtc/base/buffer.h"
kwiberg4485ffb2016-04-26 08:14:39 -070017#include "webrtc/base/constructormagic.h"
danilchap1edb7ab2016-04-20 05:25:10 -070018#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
19
20namespace webrtc {
21struct RTPHeader;
22class RtpHeaderExtensionMap;
23class Random;
24
25namespace rtp {
26class 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
35 // Parse and move given buffer into Packet.
36 bool Parse(rtc::Buffer packet);
37
38 // Maps parsed extensions to their types to allow use of GetExtension.
39 // Used after parsing when |extensions| can't be provided until base rtp
40 // header is parsed.
41 void IdentifyExtensions(const ExtensionManager* extensions);
42
43 // Header.
44 bool Marker() const;
45 uint8_t PayloadType() const;
46 uint16_t SequenceNumber() const;
47 uint32_t Timestamp() const;
48 uint32_t Ssrc() const;
49 std::vector<uint32_t> Csrcs() const;
50
51 // TODO(danilchap): Remove this function when all code update to use RtpPacket
52 // directly. Function is there just for easier backward compatibilty.
53 void GetHeader(RTPHeader* header) const;
54
55 size_t headers_size() const;
56
57 // Payload.
58 size_t payload_size() const;
59 size_t padding_size() const;
60 const uint8_t* payload() const;
61
62 // Buffer.
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 CopyHeader(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, typename... Values>
87 bool GetExtension(Values...) const;
88
89 template <typename Extension, typename... Values>
90 bool SetExtension(Values...);
91
92 template <typename Extension>
93 bool ReserveExtension();
94
95 // Reserve size_bytes for payload. Returns nullptr on failure.
96 uint8_t* AllocatePayload(size_t size_bytes);
97 void SetPayloadSize(size_t size_bytes);
98 bool SetPadding(uint8_t size_bytes, Random* random);
99
100 protected:
101 // |extensions| required for SetExtension/ReserveExtension functions during
102 // packet creating and used if available in Parse function.
103 // Adding and getting extensions will fail until |extensions| is
104 // provided via constructor or IdentifyExtensions function.
105 explicit Packet(const ExtensionManager* extensions);
106 Packet(const ExtensionManager* extensions, size_t capacity);
107 virtual ~Packet();
108
109 private:
110 struct ExtensionInfo {
111 ExtensionType type;
112 uint16_t offset;
113 uint8_t length;
114 };
115
116 // Helper function for Parse. Fill header fields using data in given buffer,
117 // but does not touch packet own buffer, leaving packet in invalid state.
118 bool ParseBuffer(const uint8_t* buffer, size_t size);
119
120 // Find an extension based on the type field of the parameter.
121 // If found, length field would be validated, the offset field will be set
122 // and true returned,
123 // otherwise the parameter will be unchanged and false is returned.
124 bool FindExtension(ExtensionType type,
125 uint8_t length,
126 uint16_t* offset) const;
127
128 // Find or allocate an extension, based on the type field of the parameter.
129 // If found, the length field be checked against what is already registered
130 // and the offset field will be set, then true is returned. If allocated, the
131 // length field will be used for allocation and the offset update to indicate
132 // position, the true is returned.
133 // If not found and allocations fails, false is returned and parameter remains
134 // unchanged.
135 bool AllocateExtension(ExtensionType type, uint8_t length, uint16_t* offset);
136
137 uint8_t* WriteAt(size_t offset);
138 void WriteAt(size_t offset, uint8_t byte);
139
140 const ExtensionManager* extensions_;
141
142 // Header.
143 bool marker_;
144 uint8_t payload_type_;
145 uint8_t padding_size_;
146 uint16_t sequence_number_;
147 uint32_t timestamp_;
148 uint32_t ssrc_;
149 size_t payload_offset_; // Match header size with csrcs and extensions.
150 size_t payload_size_;
151
152 uint8_t num_extensions_ = 0;
153 ExtensionInfo extension_entries_[kMaxExtensionHeaders];
154 uint16_t extensions_size_ = 0; // Unaligned.
155 rtc::Buffer buffer_;
156
157 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Packet);
158};
159
160template <typename Extension, typename... Values>
161bool Packet::GetExtension(Values... values) const {
162 uint16_t offset = 0;
163 if (!FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
164 return false;
165 return Extension::Parse(data() + offset, values...);
166}
167
168template <typename Extension, typename... Values>
169bool Packet::SetExtension(Values... values) {
170 uint16_t offset = 0;
171 if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
172 return false;
173 return Extension::Write(WriteAt(offset), values...);
174}
175
176template <typename Extension>
177bool Packet::ReserveExtension() {
178 uint16_t offset = 0;
179 if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
180 return false;
181 memset(WriteAt(offset), 0, Extension::kValueSizeBytes);
182 return true;
183}
184} // namespace rtp
185} // namespace webrtc
186
187#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_