tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rtp_packet.h (10287B)


      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 MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
     11 #define MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <cstring>
     16 #include <optional>
     17 #include <string>
     18 #include <utility>
     19 #include <vector>
     20 
     21 #include "api/array_view.h"
     22 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
     23 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     24 #include "rtc_base/copy_on_write_buffer.h"
     25 
     26 namespace webrtc {
     27 
     28 class RtpPacket {
     29 public:
     30  using ExtensionType = RTPExtensionType;
     31  using ExtensionManager = RtpHeaderExtensionMap;
     32 
     33  // `extensions` required for SetExtension/ReserveExtension functions during
     34  // packet creating and used if available in Parse function.
     35  // Adding and getting extensions will fail until `extensions` is
     36  // provided via constructor or IdentifyExtensions function.
     37  // |*extensions| is only accessed during construction; the pointer is not
     38  // stored.
     39  RtpPacket();
     40  explicit RtpPacket(const ExtensionManager* extensions);
     41  RtpPacket(const ExtensionManager* extensions, size_t capacity);
     42 
     43  RtpPacket(const RtpPacket&);
     44  RtpPacket(RtpPacket&&);
     45  RtpPacket& operator=(const RtpPacket&);
     46  RtpPacket& operator=(RtpPacket&&);
     47 
     48  ~RtpPacket();
     49 
     50  // Parse and copy given buffer into Packet.
     51  // Does not require extension map to be registered (map is only required to
     52  // read or allocate extensions in methods GetExtension, AllocateExtension,
     53  // etc.)
     54  bool Parse(const uint8_t* buffer, size_t size);
     55  bool Parse(ArrayView<const uint8_t> packet);
     56 
     57  // Parse and move given buffer into Packet.
     58  bool Parse(CopyOnWriteBuffer packet);
     59 
     60  // Maps extensions id to their types.
     61  void IdentifyExtensions(ExtensionManager extensions);
     62 
     63  // Returns the extension map used for identifying extensions in this packet.
     64  const ExtensionManager& extension_manager() const { return extensions_; }
     65 
     66  // Header.
     67  bool Marker() const { return marker_; }
     68  uint8_t PayloadType() const { return payload_type_; }
     69  uint16_t SequenceNumber() const { return sequence_number_; }
     70  uint32_t Timestamp() const { return timestamp_; }
     71  uint32_t Ssrc() const { return ssrc_; }
     72  std::vector<uint32_t> Csrcs() const;
     73 
     74  size_t headers_size() const { return payload_offset_; }
     75 
     76  // Payload.
     77  size_t payload_size() const { return payload_size_; }
     78  bool has_padding() const { return buffer_[0] & 0x20; }
     79  size_t padding_size() const { return padding_size_; }
     80  ArrayView<const uint8_t> payload() const {
     81    return MakeArrayView(data() + payload_offset_, payload_size_);
     82  }
     83  CopyOnWriteBuffer PayloadBuffer() const {
     84    return buffer_.Slice(payload_offset_, payload_size_);
     85  }
     86 
     87  // Buffer.
     88  CopyOnWriteBuffer Buffer() const { return buffer_; }
     89  size_t capacity() const { return buffer_.capacity(); }
     90  size_t size() const {
     91    return payload_offset_ + payload_size_ + padding_size_;
     92  }
     93  const uint8_t* data() const { return buffer_.cdata(); }
     94  size_t FreeCapacity() const { return capacity() - size(); }
     95  size_t MaxPayloadSize() const { return capacity() - headers_size(); }
     96 
     97  // Reset fields and buffer.
     98  void Clear();
     99 
    100  // Header setters.
    101  void CopyHeaderFrom(const RtpPacket& packet);
    102  void SetMarker(bool marker_bit);
    103  void SetPayloadType(uint8_t payload_type);
    104  void SetSequenceNumber(uint16_t seq_no);
    105  void SetTimestamp(uint32_t timestamp);
    106  void SetSsrc(uint32_t ssrc);
    107 
    108  // Fills with zeroes mutable extensions,
    109  // which are modified after FEC protection is generated.
    110  void ZeroMutableExtensions();
    111 
    112  // Removes extension of given `type`, returns false is extension was not
    113  // registered in packet's extension map or not present in the packet. Only
    114  // extension that should be removed must be registered, other extensions may
    115  // not be registered and will be preserved as is.
    116  bool RemoveExtension(ExtensionType type);
    117 
    118  // Writes csrc list. Assumes:
    119  // a) There is enough room left in buffer.
    120  // b) Extension headers, payload or padding data has not already been added.
    121  void SetCsrcs(ArrayView<const uint32_t> csrcs);
    122 
    123  // Header extensions.
    124  template <typename Extension>
    125  bool HasExtension() const;
    126  bool HasExtension(ExtensionType type) const;
    127 
    128  // Returns whether there is an associated id for the extension and thus it is
    129  // possible to set the extension.
    130  template <typename Extension>
    131  bool IsRegistered() const;
    132 
    133  template <typename Extension, typename FirstValue, typename... Values>
    134  bool GetExtension(FirstValue&&, Values&&...) const;
    135 
    136  template <typename Extension>
    137  std::optional<typename Extension::value_type> GetExtension() const;
    138 
    139  // Returns view of the raw extension or empty view on failure.
    140  template <typename Extension>
    141  ArrayView<const uint8_t> GetRawExtension() const;
    142 
    143  template <typename Extension, typename... Values>
    144  bool SetExtension(const Values&...);
    145 
    146  template <typename Extension>
    147  bool SetRawExtension(ArrayView<const uint8_t> data);
    148 
    149  template <typename Extension>
    150  bool ReserveExtension();
    151 
    152  // Find or allocate an extension `type`. Returns view of size `length`
    153  // to write raw extension to or an empty view on failure.
    154  ArrayView<uint8_t> AllocateExtension(ExtensionType type, size_t length);
    155 
    156  // Find an extension `type`.
    157  // Returns view of the raw extension or empty view on failure.
    158  ArrayView<const uint8_t> FindExtension(ExtensionType type) const;
    159 
    160  // Returns pointer to the payload of size at least `size_bytes`.
    161  // Keeps original payload, if any. If `size_bytes` is larger than current
    162  // `payload_size()`, remaining bytes are uninitialized.
    163  uint8_t* SetPayloadSize(size_t size_bytes);
    164 
    165  // Same as SetPayloadSize but doesn't guarantee to keep current payload.
    166  uint8_t* AllocatePayload(size_t size_bytes);
    167 
    168  // Sets payload size to `payload.size()` and copies `payload`.
    169  void SetPayload(ArrayView<const uint8_t> payload);
    170 
    171  bool SetPadding(size_t padding_size);
    172 
    173  // Returns debug string of RTP packet (without detailed extension info).
    174  std::string ToString() const;
    175 
    176 private:
    177  struct ExtensionInfo {
    178    explicit ExtensionInfo(uint8_t id) : ExtensionInfo(id, 0, 0) {}
    179    ExtensionInfo(uint8_t id, uint8_t length, uint16_t offset)
    180        : id(id), length(length), offset(offset) {}
    181    uint8_t id;
    182    uint8_t length;
    183    uint16_t offset;
    184  };
    185 
    186  // Helper function for Parse. Fill header fields using data in given buffer,
    187  // but does not touch packet own buffer, leaving packet in invalid state.
    188  bool ParseBuffer(const uint8_t* buffer, size_t size);
    189 
    190  // Returns pointer to extension info for a given id. Returns nullptr if not
    191  // found.
    192  const ExtensionInfo* FindExtensionInfo(int id) const;
    193 
    194  // Returns reference to extension info for a given id. Creates a new entry
    195  // with the specified id if not found.
    196  ExtensionInfo& FindOrCreateExtensionInfo(int id);
    197 
    198  // Allocates and returns place to store rtp header extension.
    199  // Returns empty arrayview on failure.
    200  ArrayView<uint8_t> AllocateRawExtension(int id, size_t length);
    201 
    202  // Promotes existing one-byte header extensions to two-byte header extensions
    203  // by rewriting the data and updates the corresponding extension offsets.
    204  void PromoteToTwoByteHeaderExtension();
    205 
    206  uint16_t SetExtensionLengthMaybeAddZeroPadding(size_t extensions_offset);
    207 
    208  uint8_t* WriteAt(size_t offset) { return buffer_.MutableData() + offset; }
    209  void WriteAt(size_t offset, uint8_t byte) {
    210    buffer_.MutableData()[offset] = byte;
    211  }
    212  const uint8_t* ReadAt(size_t offset) const { return buffer_.data() + offset; }
    213 
    214  // Header.
    215  bool marker_;
    216  uint8_t payload_type_;
    217  uint8_t padding_size_;
    218  uint16_t sequence_number_;
    219  uint32_t timestamp_;
    220  uint32_t ssrc_;
    221  size_t payload_offset_;  // Match header size with csrcs and extensions.
    222  size_t payload_size_;
    223 
    224  ExtensionManager extensions_;
    225  std::vector<ExtensionInfo> extension_entries_;
    226  size_t extensions_size_ = 0;  // Unaligned.
    227  CopyOnWriteBuffer buffer_;
    228 };
    229 
    230 template <typename Extension>
    231 bool RtpPacket::HasExtension() const {
    232  return HasExtension(Extension::kId);
    233 }
    234 
    235 template <typename Extension>
    236 bool RtpPacket::IsRegistered() const {
    237  return extensions_.IsRegistered(Extension::kId);
    238 }
    239 
    240 template <typename Extension, typename FirstValue, typename... Values>
    241 bool RtpPacket::GetExtension(FirstValue&& first, Values&&... values) const {
    242  auto raw = FindExtension(Extension::kId);
    243  if (raw.empty())
    244    return false;
    245  return Extension::Parse(raw, std::forward<FirstValue>(first),
    246                          std::forward<Values>(values)...);
    247 }
    248 
    249 template <typename Extension>
    250 std::optional<typename Extension::value_type> RtpPacket::GetExtension() const {
    251  std::optional<typename Extension::value_type> result;
    252  auto raw = FindExtension(Extension::kId);
    253  if (raw.empty() || !Extension::Parse(raw, &result.emplace()))
    254    result = std::nullopt;
    255  return result;
    256 }
    257 
    258 template <typename Extension>
    259 ArrayView<const uint8_t> RtpPacket::GetRawExtension() const {
    260  return FindExtension(Extension::kId);
    261 }
    262 
    263 template <typename Extension, typename... Values>
    264 bool RtpPacket::SetExtension(const Values&... values) {
    265  const size_t value_size = Extension::ValueSize(values...);
    266  auto buffer = AllocateExtension(Extension::kId, value_size);
    267  if (buffer.empty())
    268    return false;
    269  return Extension::Write(buffer, values...);
    270 }
    271 
    272 template <typename Extension>
    273 bool RtpPacket::SetRawExtension(ArrayView<const uint8_t> data) {
    274  ArrayView<uint8_t> buffer = AllocateExtension(Extension::kId, data.size());
    275  if (buffer.empty()) {
    276    return false;
    277  }
    278  std::memcpy(buffer.data(), data.data(), data.size());
    279  return true;
    280 }
    281 
    282 template <typename Extension>
    283 bool RtpPacket::ReserveExtension() {
    284  auto buffer = AllocateExtension(Extension::kId, Extension::kValueSizeBytes);
    285  if (buffer.empty())
    286    return false;
    287  memset(buffer.data(), 0, Extension::kValueSizeBytes);
    288  return true;
    289 }
    290 
    291 }  // namespace webrtc
    292 
    293 #endif  // MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_