summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet.cc
diff options
context:
space:
mode:
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.cc99
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