Line data Source code
1 : /*
2 : * Copyright (c) 2014 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 :
11 : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
12 :
13 : #include "webrtc/base/checks.h"
14 :
15 : namespace webrtc {
16 : namespace rtcp {
17 : constexpr size_t RtcpPacket::kHeaderLength;
18 :
19 0 : rtc::Buffer RtcpPacket::Build() const {
20 0 : rtc::Buffer packet(BlockLength());
21 :
22 0 : size_t length = 0;
23 0 : bool created = Create(packet.data(), &length, packet.capacity(), nullptr);
24 0 : RTC_DCHECK(created) << "Invalid packet is not supported.";
25 0 : RTC_DCHECK_EQ(length, packet.size())
26 0 : << "BlockLength mispredicted size used by Create";
27 :
28 0 : return packet;
29 : }
30 :
31 0 : bool RtcpPacket::BuildExternalBuffer(uint8_t* buffer,
32 : size_t max_length,
33 : PacketReadyCallback* callback) const {
34 0 : size_t index = 0;
35 0 : if (!Create(buffer, &index, max_length, callback))
36 0 : return false;
37 0 : return OnBufferFull(buffer, &index, callback);
38 : }
39 :
40 0 : bool RtcpPacket::OnBufferFull(uint8_t* packet,
41 : size_t* index,
42 : PacketReadyCallback* callback) const {
43 0 : if (*index == 0)
44 0 : return false;
45 0 : RTC_DCHECK(callback) << "Fragmentation not supported.";
46 0 : callback->OnPacketReady(packet, *index);
47 0 : *index = 0;
48 0 : return true;
49 : }
50 :
51 0 : size_t RtcpPacket::HeaderLength() const {
52 0 : size_t length_in_bytes = BlockLength();
53 0 : RTC_DCHECK_GT(length_in_bytes, 0);
54 0 : RTC_DCHECK_EQ(length_in_bytes % 4, 0) << "Padding not supported";
55 : // Length in 32-bit words without common header.
56 0 : return (length_in_bytes - kHeaderLength) / 4;
57 : }
58 :
59 : // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
60 : //
61 : // RTP header format.
62 : // 0 1 2 3
63 : // 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
64 : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65 : // |V=2|P| RC/FMT | PT | length |
66 : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 0 : void RtcpPacket::CreateHeader(
68 : uint8_t count_or_format, // Depends on packet type.
69 : uint8_t packet_type,
70 : size_t length,
71 : uint8_t* buffer,
72 : size_t* pos) {
73 0 : RTC_DCHECK_LE(length, 0xffffU);
74 0 : RTC_DCHECK_LE(count_or_format, 0x1f);
75 0 : constexpr uint8_t kVersionBits = 2 << 6;
76 0 : constexpr uint8_t kNoPaddingBit = 0 << 5;
77 0 : buffer[*pos + 0] = kVersionBits | kNoPaddingBit | count_or_format;
78 0 : buffer[*pos + 1] = packet_type;
79 0 : buffer[*pos + 2] = (length >> 8) & 0xff;
80 0 : buffer[*pos + 3] = length & 0xff;
81 0 : *pos += kHeaderLength;
82 0 : }
83 :
84 : } // namespace rtcp
85 : } // namespace webrtc
|