blob: ca189dbe0d23bbe0c8f9da3dacf7649425aed235 [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;
danilchap653063f2017-04-03 06:16:30 -070031 static constexpr int kMinExtensionId = 1;
32 static constexpr int kMaxExtensionId = 14;
danilchap1edb7ab2016-04-20 05:25:10 -070033
34 // Parse and copy given buffer into Packet.
35 bool Parse(const uint8_t* buffer, size_t size);
brandtrb29e6522016-12-21 06:37:18 -080036 bool Parse(rtc::ArrayView<const uint8_t> packet);
danilchap1edb7ab2016-04-20 05:25:10 -070037
38 // Parse and move given buffer into Packet.
Danil Chapovalov31e4e802016-08-03 18:27:40 +020039 bool Parse(rtc::CopyOnWriteBuffer packet);
danilchap1edb7ab2016-04-20 05:25:10 -070040
danilchap70f39a32016-12-16 05:48:18 -080041 // Maps extensions id to their types.
42 void IdentifyExtensions(const ExtensionManager& extensions);
danilchap1edb7ab2016-04-20 05:25:10 -070043
44 // Header.
45 bool Marker() const;
46 uint8_t PayloadType() const;
47 uint16_t SequenceNumber() const;
48 uint32_t Timestamp() const;
49 uint32_t Ssrc() const;
50 std::vector<uint32_t> Csrcs() const;
51
52 // TODO(danilchap): Remove this function when all code update to use RtpPacket
53 // directly. Function is there just for easier backward compatibilty.
54 void GetHeader(RTPHeader* header) const;
55
56 size_t headers_size() const;
57
58 // Payload.
59 size_t payload_size() const;
60 size_t padding_size() const;
danilchap96c15872016-11-21 01:35:29 -080061 rtc::ArrayView<const uint8_t> payload() const;
danilchap1edb7ab2016-04-20 05:25:10 -070062
63 // Buffer.
Danil Chapovalov31e4e802016-08-03 18:27:40 +020064 rtc::CopyOnWriteBuffer Buffer() const;
danilchap1edb7ab2016-04-20 05:25:10 -070065 size_t capacity() const;
66 size_t size() const;
67 const uint8_t* data() const;
68 size_t FreeCapacity() const;
69 size_t MaxPayloadSize() const;
70
71 // Reset fields and buffer.
72 void Clear();
73
74 // Header setters.
Danil Chapovalov31e4e802016-08-03 18:27:40 +020075 void CopyHeaderFrom(const Packet& packet);
danilchap1edb7ab2016-04-20 05:25:10 -070076 void SetMarker(bool marker_bit);
77 void SetPayloadType(uint8_t payload_type);
78 void SetSequenceNumber(uint16_t seq_no);
79 void SetTimestamp(uint32_t timestamp);
80 void SetSsrc(uint32_t ssrc);
81
82 // Writes csrc list. Assumes:
83 // a) There is enough room left in buffer.
84 // b) Extension headers, payload or padding data has not already been added.
85 void SetCsrcs(const std::vector<uint32_t>& csrcs);
86
87 // Header extensions.
Danil Chapovalov5e57b172016-09-02 19:15:59 +020088 template <typename Extension>
89 bool HasExtension() const;
90
danilchap1edb7ab2016-04-20 05:25:10 -070091 template <typename Extension, typename... Values>
92 bool GetExtension(Values...) const;
93
94 template <typename Extension, typename... Values>
95 bool SetExtension(Values...);
96
97 template <typename Extension>
98 bool ReserveExtension();
99
danilchap653063f2017-04-03 06:16:30 -0700100 // Following 4 helpers identify rtp header extension by |id| negotiated with
101 // remote peer and written in an rtp packet.
102 bool HasRawExtension(int id) const;
103
104 // Returns place where extension with |id| is stored.
105 // Returns empty arrayview if extension is not present.
106 rtc::ArrayView<const uint8_t> GetRawExtension(int id) const;
107
108 // Allocates and store header extension. Returns true on success.
109 bool SetRawExtension(int id, rtc::ArrayView<const uint8_t> data);
110
111 // Allocates and returns place to store rtp header extension.
112 // Returns empty arrayview on failure.
113 rtc::ArrayView<uint8_t> AllocateRawExtension(int id, size_t length);
114
danilchap1edb7ab2016-04-20 05:25:10 -0700115 // Reserve size_bytes for payload. Returns nullptr on failure.
danilchap07a01b32017-03-29 07:33:13 -0700116 uint8_t* SetPayloadSize(size_t size_bytes);
117 // Same as SetPayloadSize but doesn't guarantee to keep current payload.
danilchap1edb7ab2016-04-20 05:25:10 -0700118 uint8_t* AllocatePayload(size_t size_bytes);
danilchap1edb7ab2016-04-20 05:25:10 -0700119 bool SetPadding(uint8_t size_bytes, Random* random);
120
121 protected:
122 // |extensions| required for SetExtension/ReserveExtension functions during
123 // packet creating and used if available in Parse function.
124 // Adding and getting extensions will fail until |extensions| is
125 // provided via constructor or IdentifyExtensions function.
danilchap70f39a32016-12-16 05:48:18 -0800126 Packet();
danilchap1edb7ab2016-04-20 05:25:10 -0700127 explicit Packet(const ExtensionManager* extensions);
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200128 Packet(const Packet&) = default;
danilchap1edb7ab2016-04-20 05:25:10 -0700129 Packet(const ExtensionManager* extensions, size_t capacity);
130 virtual ~Packet();
131
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200132 Packet& operator=(const Packet&) = default;
133
danilchap1edb7ab2016-04-20 05:25:10 -0700134 private:
135 struct ExtensionInfo {
136 ExtensionType type;
137 uint16_t offset;
138 uint8_t length;
139 };
140
141 // Helper function for Parse. Fill header fields using data in given buffer,
142 // but does not touch packet own buffer, leaving packet in invalid state.
143 bool ParseBuffer(const uint8_t* buffer, size_t size);
144
danilchap978504e2017-04-06 01:03:53 -0700145 // Find an extension |type|.
146 // Returns view of the raw extension or empty view on failure.
147 rtc::ArrayView<const uint8_t> FindExtension(ExtensionType type) const;
danilchap1edb7ab2016-04-20 05:25:10 -0700148
danilchap653063f2017-04-03 06:16:30 -0700149 // Find or allocate an extension |type|. Returns view of size |length|
150 // to write raw extension to or an empty view on failure.
151 rtc::ArrayView<uint8_t> AllocateExtension(ExtensionType type, size_t length);
danilchap1edb7ab2016-04-20 05:25:10 -0700152
153 uint8_t* WriteAt(size_t offset);
154 void WriteAt(size_t offset, uint8_t byte);
155
danilchap1edb7ab2016-04-20 05:25:10 -0700156 // Header.
157 bool marker_;
158 uint8_t payload_type_;
159 uint8_t padding_size_;
160 uint16_t sequence_number_;
161 uint32_t timestamp_;
162 uint32_t ssrc_;
163 size_t payload_offset_; // Match header size with csrcs and extensions.
164 size_t payload_size_;
165
danilchap1edb7ab2016-04-20 05:25:10 -0700166 ExtensionInfo extension_entries_[kMaxExtensionHeaders];
167 uint16_t extensions_size_ = 0; // Unaligned.
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200168 rtc::CopyOnWriteBuffer buffer_;
danilchap1edb7ab2016-04-20 05:25:10 -0700169};
170
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200171template <typename Extension>
172bool Packet::HasExtension() const {
danilchap978504e2017-04-06 01:03:53 -0700173 return !FindExtension(Extension::kId).empty();
Danil Chapovalov5e57b172016-09-02 19:15:59 +0200174}
175
danilchap1edb7ab2016-04-20 05:25:10 -0700176template <typename Extension, typename... Values>
177bool Packet::GetExtension(Values... values) const {
danilchap978504e2017-04-06 01:03:53 -0700178 auto raw = FindExtension(Extension::kId);
179 if (raw.empty())
danilchap1edb7ab2016-04-20 05:25:10 -0700180 return false;
danilchap978504e2017-04-06 01:03:53 -0700181 return Extension::Parse(raw, values...);
danilchap1edb7ab2016-04-20 05:25:10 -0700182}
183
184template <typename Extension, typename... Values>
185bool Packet::SetExtension(Values... values) {
danilchap653063f2017-04-03 06:16:30 -0700186 auto buffer = AllocateExtension(Extension::kId, Extension::kValueSizeBytes);
187 if (buffer.empty())
danilchap1edb7ab2016-04-20 05:25:10 -0700188 return false;
danilchap653063f2017-04-03 06:16:30 -0700189 return Extension::Write(buffer.data(), values...);
danilchap1edb7ab2016-04-20 05:25:10 -0700190}
191
192template <typename Extension>
193bool Packet::ReserveExtension() {
danilchap653063f2017-04-03 06:16:30 -0700194 auto buffer = AllocateExtension(Extension::kId, Extension::kValueSizeBytes);
195 if (buffer.empty())
danilchap1edb7ab2016-04-20 05:25:10 -0700196 return false;
danilchap653063f2017-04-03 06:16:30 -0700197 memset(buffer.data(), 0, Extension::kValueSizeBytes);
danilchap1edb7ab2016-04-20 05:25:10 -0700198 return true;
199}
200} // namespace rtp
201} // namespace webrtc
202
203#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_