/* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_ #include #include "webrtc/base/basictypes.h" #include "webrtc/base/buffer.h" #include "webrtc/base/constructormagic.h" #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" namespace webrtc { struct RTPHeader; class RtpHeaderExtensionMap; class Random; namespace rtp { class Packet { public: using ExtensionType = RTPExtensionType; using ExtensionManager = RtpHeaderExtensionMap; static constexpr size_t kMaxExtensionHeaders = 14; // Parse and copy given buffer into Packet. bool Parse(const uint8_t* buffer, size_t size); // Parse and move given buffer into Packet. bool Parse(rtc::Buffer packet); // Maps parsed extensions to their types to allow use of GetExtension. // Used after parsing when |extensions| can't be provided until base rtp // header is parsed. void IdentifyExtensions(const ExtensionManager* extensions); // Header. bool Marker() const; uint8_t PayloadType() const; uint16_t SequenceNumber() const; uint32_t Timestamp() const; uint32_t Ssrc() const; std::vector Csrcs() const; // TODO(danilchap): Remove this function when all code update to use RtpPacket // directly. Function is there just for easier backward compatibilty. void GetHeader(RTPHeader* header) const; size_t headers_size() const; // Payload. size_t payload_size() const; size_t padding_size() const; const uint8_t* payload() const; // Buffer. size_t capacity() const; size_t size() const; const uint8_t* data() const; size_t FreeCapacity() const; size_t MaxPayloadSize() const; // Reset fields and buffer. void Clear(); // Header setters. void CopyHeader(const Packet& packet); void SetMarker(bool marker_bit); void SetPayloadType(uint8_t payload_type); void SetSequenceNumber(uint16_t seq_no); void SetTimestamp(uint32_t timestamp); void SetSsrc(uint32_t ssrc); // Writes csrc list. Assumes: // a) There is enough room left in buffer. // b) Extension headers, payload or padding data has not already been added. void SetCsrcs(const std::vector& csrcs); // Header extensions. template bool GetExtension(Values...) const; template bool SetExtension(Values...); template bool ReserveExtension(); // Reserve size_bytes for payload. Returns nullptr on failure. uint8_t* AllocatePayload(size_t size_bytes); void SetPayloadSize(size_t size_bytes); bool SetPadding(uint8_t size_bytes, Random* random); protected: // |extensions| required for SetExtension/ReserveExtension functions during // packet creating and used if available in Parse function. // Adding and getting extensions will fail until |extensions| is // provided via constructor or IdentifyExtensions function. explicit Packet(const ExtensionManager* extensions); Packet(const ExtensionManager* extensions, size_t capacity); virtual ~Packet(); private: struct ExtensionInfo { ExtensionType type; uint16_t offset; uint8_t length; }; // Helper function for Parse. Fill header fields using data in given buffer, // but does not touch packet own buffer, leaving packet in invalid state. bool ParseBuffer(const uint8_t* buffer, size_t size); // Find an extension based on the type field of the parameter. // If found, length field would be validated, the offset field will be set // and true returned, // otherwise the parameter will be unchanged and false is returned. bool FindExtension(ExtensionType type, uint8_t length, uint16_t* offset) const; // Find or allocate an extension, based on the type field of the parameter. // If found, the length field be checked against what is already registered // and the offset field will be set, then true is returned. If allocated, the // length field will be used for allocation and the offset update to indicate // position, the true is returned. // If not found and allocations fails, false is returned and parameter remains // unchanged. bool AllocateExtension(ExtensionType type, uint8_t length, uint16_t* offset); uint8_t* WriteAt(size_t offset); void WriteAt(size_t offset, uint8_t byte); const ExtensionManager* extensions_; // Header. bool marker_; uint8_t payload_type_; uint8_t padding_size_; uint16_t sequence_number_; uint32_t timestamp_; uint32_t ssrc_; size_t payload_offset_; // Match header size with csrcs and extensions. size_t payload_size_; uint8_t num_extensions_ = 0; ExtensionInfo extension_entries_[kMaxExtensionHeaders]; uint16_t extensions_size_ = 0; // Unaligned. rtc::Buffer buffer_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Packet); }; template bool Packet::GetExtension(Values... values) const { uint16_t offset = 0; if (!FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset)) return false; return Extension::Parse(data() + offset, values...); } template bool Packet::SetExtension(Values... values) { uint16_t offset = 0; if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset)) return false; return Extension::Write(WriteAt(offset), values...); } template bool Packet::ReserveExtension() { uint16_t offset = 0; if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset)) return false; memset(WriteAt(offset), 0, Extension::kValueSizeBytes); return true; } } // namespace rtp } // namespace webrtc #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_