blob: 2b3d38ec49f0310dcea3b639996c265b018bf479 [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
danilchap96c15872016-11-21 01:35:29 -080015#include "webrtc/base/array_view.h"
danilchap1edb7ab2016-04-20 05:25:10 -070016#include "webrtc/base/basictypes.h"
Danil Chapovalov31e4e802016-08-03 18:27:40 +020017#include "webrtc/base/copyonwritebuffer.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.
Danil Chapovalov31e4e802016-08-03 18:27:40 +020036 bool Parse(rtc::CopyOnWriteBuffer packet);
danilchap1edb7ab2016-04-20 05:25:10 -070037
danilchap70f39a32016-12-16 05:48:18 -080038 // Maps extensions id to their types.
39 void IdentifyExtensions(const ExtensionManager& extensions);
danilchap1edb7ab2016-04-20 05:25:10 -070040
41 // Header.
42 bool Marker() const;
43 uint8_t PayloadType() const;
44 uint16_t SequenceNumber() const;
45 uint32_t Timestamp() const;
46 uint32_t Ssrc() const;
47 std::vector<uint32_t> Csrcs() const;
48
49 // TODO(danilchap): Remove this function when all code update to use RtpPacket
50 // directly. Function is there just for easier backward compatibilty.
51 void GetHeader(RTPHeader* header) const;
52
53 size_t headers_size() const;
54
55 // Payload.
56 size_t payload_size() const;
57 size_t padding_size() const;
danilchap96c15872016-11-21 01:35:29 -080058 rtc::ArrayView<const uint8_t> payload() const;
danilchap1edb7ab2016-04-20 05:25:10 -070059
60 // Buffer.
Danil Chapovalov31e4e802016-08-03 18:27:40 +020061 rtc::CopyOnWriteBuffer Buffer() const;
danilchap1edb7ab2016-04-20 05:25:10 -070062 size_t capacity() const;
63 size_t size() const;
64 const uint8_t* data() const;
65 size_t FreeCapacity() const;
66 size_t MaxPayloadSize() const;
67
68 // Reset fields and buffer.
69 void Clear();
70
71 // Header setters.
Danil Chapovalov31e4e802016-08-03 18:27:40 +020072 void CopyHeaderFrom(const Packet& packet);
danilchap1edb7ab2016-04-20 05:25:10 -070073 void SetMarker(bool marker_bit);
74 void SetPayloadType(uint8_t payload_type);
75 void SetSequenceNumber(uint16_t seq_no);
76 void SetTimestamp(uint32_t timestamp);
77 void SetSsrc(uint32_t ssrc);
78
79 // Writes csrc list. Assumes:
80 // a) There is enough room left in buffer.
81 // b) Extension headers, payload or padding data has not already been added.
82 void SetCsrcs(const std::vector<uint32_t>& csrcs);
83
84 // Header extensions.
Danil Chapovalov5e57b172016-09-02 19:15:59 +020085 template <typename Extension>
86 bool HasExtension() const;
87
danilchap1edb7ab2016-04-20 05:25:10 -070088 template <typename Extension, typename... Values>
89 bool GetExtension(Values...) const;
90
91 template <typename Extension, typename... Values>
92 bool SetExtension(Values...);
93
94 template <typename Extension>
95 bool ReserveExtension();
96
97 // Reserve size_bytes for payload. Returns nullptr on failure.
98 uint8_t* AllocatePayload(size_t size_bytes);
99 void SetPayloadSize(size_t size_bytes);
100 bool SetPadding(uint8_t size_bytes, Random* random);
101
102 protected:
103 // |extensions| required for SetExtension/ReserveExtension functions during
104 // packet creating and used if available in Parse function.
105 // Adding and getting extensions will fail until |extensions| is
106 // provided via constructor or IdentifyExtensions function.
danilchap70f39a32016-12-16 05:48:18 -0800107 Packet();
danilchap1edb7ab2016-04-20 05:25:10 -0700108 explicit Packet(const ExtensionManager* extensions);
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200109 Packet(const Packet&) = default;
danilchap1edb7ab2016-04-20 05:25:10 -0700110 Packet(const ExtensionManager* extensions, size_t capacity);
111 virtual ~Packet();
112
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200113 Packet& operator=(const Packet&) = default;
114
danilchap1edb7ab2016-04-20 05:25:10 -0700115 private:
116 struct ExtensionInfo {
117 ExtensionType type;
118 uint16_t offset;
119 uint8_t length;
120 };
121
122 // Helper function for Parse. Fill header fields using data in given buffer,
123 // but does not touch packet own buffer, leaving packet in invalid state.
124 bool ParseBuffer(const uint8_t* buffer, size_t size);
125
126 // Find an extension based on the type field of the parameter.
127 // If found, length field would be validated, the offset field will be set
128 // and true returned,
129 // otherwise the parameter will be unchanged and false is returned.
130 bool FindExtension(ExtensionType type,
131 uint8_t length,
132 uint16_t* offset) const;
133
134 // Find or allocate an extension, based on the type field of the parameter.
135 // If found, the length field be checked against what is already registered
136 // and the offset field will be set, then true is returned. If allocated, the
137 // length field will be used for allocation and the offset update to indicate
138 // position, the true is returned.
139 // If not found and allocations fails, false is returned and parameter remains
140 // unchanged.
141 bool AllocateExtension(ExtensionType type, uint8_t length, uint16_t* offset);
142
143 uint8_t* WriteAt(size_t offset);
144 void WriteAt(size_t offset, uint8_t byte);
145
danilchap1edb7ab2016-04-20 05:25:10 -0700146 // Header.
147 bool marker_;
148 uint8_t payload_type_;
149 uint8_t padding_size_;
150 uint16_t sequence_number_;
151 uint32_t timestamp_;
152 uint32_t ssrc_;
153 size_t payload_offset_; // Match header size with csrcs and extensions.
154 size_t payload_size_;
155
danilchap1edb7ab2016-04-20 05:25:10 -0700156 ExtensionInfo extension_entries_[kMaxExtensionHeaders];
157 uint16_t extensions_size_ = 0; // Unaligned.
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200158 rtc::CopyOnWriteBuffer buffer_;
danilchap1edb7ab2016-04-20 05:25:10 -0700159};
160
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200161template <typename Extension>
162bool Packet::HasExtension() const {
163 uint16_t offset = 0;
164 return FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset);
165}
166
danilchap1edb7ab2016-04-20 05:25:10 -0700167template <typename Extension, typename... Values>
168bool Packet::GetExtension(Values... values) const {
169 uint16_t offset = 0;
170 if (!FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
171 return false;
172 return Extension::Parse(data() + offset, values...);
173}
174
175template <typename Extension, typename... Values>
176bool Packet::SetExtension(Values... values) {
177 uint16_t offset = 0;
178 if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
179 return false;
180 return Extension::Write(WriteAt(offset), values...);
181}
182
183template <typename Extension>
184bool Packet::ReserveExtension() {
185 uint16_t offset = 0;
186 if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
187 return false;
188 memset(WriteAt(offset), 0, Extension::kValueSizeBytes);
189 return true;
190}
191} // namespace rtp
192} // namespace webrtc
193
194#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_