diff options
Diffstat (limited to 'third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet.cc')
-rw-r--r-- | third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet.cc | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet.cc new file mode 100644 index 0000000000..bac03e73d2 --- /dev/null +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet.cc @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014 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. + */ + +#include "modules/rtp_rtcp/source/rtcp_packet.h" + +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "rtc_base/checks.h" + +namespace webrtc { +namespace rtcp { +constexpr size_t RtcpPacket::kHeaderLength; + +rtc::Buffer RtcpPacket::Build() const { + rtc::Buffer packet(BlockLength()); + + size_t length = 0; + bool created = Create(packet.data(), &length, packet.capacity(), nullptr); + RTC_DCHECK(created) << "Invalid packet is not supported."; + RTC_DCHECK_EQ(length, packet.size()) + << "BlockLength mispredicted size used by Create"; + + return packet; +} + +bool RtcpPacket::Build(size_t max_length, PacketReadyCallback callback) const { + RTC_CHECK_LE(max_length, IP_PACKET_SIZE); + uint8_t buffer[IP_PACKET_SIZE]; + size_t index = 0; + if (!Create(buffer, &index, max_length, callback)) + return false; + return OnBufferFull(buffer, &index, callback); +} + +bool RtcpPacket::OnBufferFull(uint8_t* packet, + size_t* index, + PacketReadyCallback callback) const { + if (*index == 0) + return false; + RTC_DCHECK(callback) << "Fragmentation not supported."; + callback(rtc::ArrayView<const uint8_t>(packet, *index)); + *index = 0; + return true; +} + +size_t RtcpPacket::HeaderLength() const { + size_t length_in_bytes = BlockLength(); + RTC_DCHECK_GT(length_in_bytes, 0); + RTC_DCHECK_EQ(length_in_bytes % 4, 0) + << "Padding must be handled by each subclass."; + // Length in 32-bit words without common header. + return (length_in_bytes - kHeaderLength) / 4; +} + +// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications. +// +// RTP header format. +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |V=2|P| RC/FMT | PT | length | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +void RtcpPacket::CreateHeader( + size_t count_or_format, // Depends on packet type. + uint8_t packet_type, + size_t length, + uint8_t* buffer, + size_t* pos) { + CreateHeader(count_or_format, packet_type, length, /*padding=*/false, buffer, + pos); +} + +void RtcpPacket::CreateHeader( + size_t count_or_format, // Depends on packet type. + uint8_t packet_type, + size_t length, + bool padding, + uint8_t* buffer, + size_t* pos) { + RTC_DCHECK_LE(length, 0xffffU); + RTC_DCHECK_LE(count_or_format, 0x1f); + constexpr uint8_t kVersionBits = 2 << 6; + uint8_t padding_bit = padding ? 1 << 5 : 0; + buffer[*pos + 0] = + kVersionBits | padding_bit | static_cast<uint8_t>(count_or_format); + buffer[*pos + 1] = packet_type; + buffer[*pos + 2] = (length >> 8) & 0xff; + buffer[*pos + 3] = length & 0xff; + *pos += kHeaderLength; +} + +} // namespace rtcp +} // namespace webrtc |