xref: /aosp_15_r20/external/openscreen/cast/streaming/rtp_defines.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #ifndef CAST_STREAMING_RTP_DEFINES_H_
6*3f982cf4SFabien Sanglard #define CAST_STREAMING_RTP_DEFINES_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <stdint.h>
9*3f982cf4SFabien Sanglard 
10*3f982cf4SFabien Sanglard #include "cast/streaming/constants.h"
11*3f982cf4SFabien Sanglard 
12*3f982cf4SFabien Sanglard namespace openscreen {
13*3f982cf4SFabien Sanglard namespace cast {
14*3f982cf4SFabien Sanglard 
15*3f982cf4SFabien Sanglard // Note: Cast Streaming uses a subset of the messages in the RTP/RTCP
16*3f982cf4SFabien Sanglard // specification, but also adds some of its own extensions. See:
17*3f982cf4SFabien Sanglard // https://tools.ietf.org/html/rfc3550
18*3f982cf4SFabien Sanglard 
19*3f982cf4SFabien Sanglard // Uniquely identifies one packet within a frame. These are sequence numbers,
20*3f982cf4SFabien Sanglard // starting at 0. Each Cast RTP packet also includes the "last ID" so that a
21*3f982cf4SFabien Sanglard // receiver always knows the range of valid FramePacketIds for a given frame.
22*3f982cf4SFabien Sanglard using FramePacketId = uint16_t;
23*3f982cf4SFabien Sanglard 
24*3f982cf4SFabien Sanglard // A special FramePacketId value meant to represent "all packets lost" in Cast
25*3f982cf4SFabien Sanglard // RTCP Feedback messages.
26*3f982cf4SFabien Sanglard constexpr FramePacketId kAllPacketsLost = 0xffff;
27*3f982cf4SFabien Sanglard constexpr FramePacketId kMaxAllowedFramePacketId = kAllPacketsLost - 1;
28*3f982cf4SFabien Sanglard 
29*3f982cf4SFabien Sanglard // The maximum size of any RTP or RTCP packet, in bytes. The calculation below
30*3f982cf4SFabien Sanglard // is: Standard Ethernet MTU bytes minus IP header bytes minus UDP header bytes.
31*3f982cf4SFabien Sanglard // The remainder is available for RTP/RTCP packet data (header + payload).
32*3f982cf4SFabien Sanglard //
33*3f982cf4SFabien Sanglard // A nice explanation of this: https://jvns.ca/blog/2017/02/07/mtu/
34*3f982cf4SFabien Sanglard //
35*3f982cf4SFabien Sanglard // Constants are provided here for UDP over IPv4 and IPv6 on Ethernet. Other
36*3f982cf4SFabien Sanglard // transports and network mediums will need additional consideration, alternate
37*3f982cf4SFabien Sanglard // calculations. Note that MTU is dynamic, depending on the path the packets
38*3f982cf4SFabien Sanglard // take between two endpoints (the 1500 here is just a commonly-used value for
39*3f982cf4SFabien Sanglard // LAN Ethernet).
40*3f982cf4SFabien Sanglard constexpr int kMaxRtpPacketSizeForIpv4UdpOnEthernet = 1500 - 20 - 8;
41*3f982cf4SFabien Sanglard constexpr int kMaxRtpPacketSizeForIpv6UdpOnEthernet = 1500 - 40 - 8;
42*3f982cf4SFabien Sanglard 
43*3f982cf4SFabien Sanglard // The Cast RTP packet header:
44*3f982cf4SFabien Sanglard //
45*3f982cf4SFabien Sanglard //  0                   1                   2                   3
46*3f982cf4SFabien Sanglard //  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
47*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ^
48*3f982cf4SFabien Sanglard // |V=2|P|X| CC=0  |M|      PT     |      sequence number          | |
49*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+RTP
50*3f982cf4SFabien Sanglard // +                         RTP timestamp                         |Spec
51*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
52*3f982cf4SFabien Sanglard // +         synchronization source (SSRC) identifier              | v
53*3f982cf4SFabien Sanglard // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
54*3f982cf4SFabien Sanglard // |K|R| EXT count |  FID          |              PID              | ^
55*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Cast
56*3f982cf4SFabien Sanglard // |             Max PID           |  optional fields, extensions,  Spec
57*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  then payload...                v
58*3f982cf4SFabien Sanglard //
59*3f982cf4SFabien Sanglard // Byte 0:  Version 2, no padding, no RTP extensions, no CSRCs.
60*3f982cf4SFabien Sanglard // Byte 1:  Marker bit indicates whether this is the last packet, followed by a
61*3f982cf4SFabien Sanglard //          7-bit payload type.
62*3f982cf4SFabien Sanglard // Byte 12: Key Frame bit, followed by "RFID will be provided" bit, followed by
63*3f982cf4SFabien Sanglard //          6 bits specifying the number of extensions that will be provided.
64*3f982cf4SFabien Sanglard 
65*3f982cf4SFabien Sanglard // The minimum-possible valid size of a Cast RTP packet (i.e., no optional
66*3f982cf4SFabien Sanglard // fields, extensions, nor payload).
67*3f982cf4SFabien Sanglard constexpr int kRtpPacketMinValidSize = 18;
68*3f982cf4SFabien Sanglard 
69*3f982cf4SFabien Sanglard // All Cast RTP packets must carry the version 2 flag, not use padding, not use
70*3f982cf4SFabien Sanglard // RTP extensions, and have zero CSRCs.
71*3f982cf4SFabien Sanglard constexpr uint8_t kRtpRequiredFirstByte = 0b10000000;
72*3f982cf4SFabien Sanglard 
73*3f982cf4SFabien Sanglard // Bitmasks to isolate fields within byte 2 of the Cast RTP header.
74*3f982cf4SFabien Sanglard constexpr uint8_t kRtpMarkerBitMask = 0b10000000;
75*3f982cf4SFabien Sanglard constexpr uint8_t kRtpPayloadTypeMask = 0b01111111;
76*3f982cf4SFabien Sanglard 
77*3f982cf4SFabien Sanglard // Describes the content being transported over RTP streams. These are Cast
78*3f982cf4SFabien Sanglard // Streaming specific assignments, within the "dynamic" range provided by
79*3f982cf4SFabien Sanglard // IANA. Note that this Cast Streaming implementation does not manipulate
80*3f982cf4SFabien Sanglard // already-encoded data, and so these payload types are only "informative" in
81*3f982cf4SFabien Sanglard // purpose and can be used to check for corruption while parsing packets.
82*3f982cf4SFabien Sanglard enum class RtpPayloadType : uint8_t {
83*3f982cf4SFabien Sanglard   kNull = 0,
84*3f982cf4SFabien Sanglard 
85*3f982cf4SFabien Sanglard   kAudioFirst = 96,
86*3f982cf4SFabien Sanglard   kAudioOpus = 96,
87*3f982cf4SFabien Sanglard   kAudioAac = 97,
88*3f982cf4SFabien Sanglard   kAudioPcm16 = 98,
89*3f982cf4SFabien Sanglard   kAudioVarious = 99,  // Codec being used is not fixed.
90*3f982cf4SFabien Sanglard 
91*3f982cf4SFabien Sanglard   kVideoFirst = 100,
92*3f982cf4SFabien Sanglard   kVideoVp8 = 100,
93*3f982cf4SFabien Sanglard   kVideoH264 = 101,
94*3f982cf4SFabien Sanglard   kVideoVarious = 102,  // Codec being used is not fixed.
95*3f982cf4SFabien Sanglard   kVideoVp9 = 103,
96*3f982cf4SFabien Sanglard   kVideoAv1 = 104,
97*3f982cf4SFabien Sanglard   kVideoLast = kVideoAv1,
98*3f982cf4SFabien Sanglard 
99*3f982cf4SFabien Sanglard   // Some AndroidTV receivers require the payload type for audio to be 127, and
100*3f982cf4SFabien Sanglard   // video to be 96; regardless of the codecs actually being used. This is
101*3f982cf4SFabien Sanglard   // definitely out-of-spec, and inconsistent with the audio versus video range
102*3f982cf4SFabien Sanglard   // of values, but must be taken into account for backwards-compatibility.
103*3f982cf4SFabien Sanglard   kAudioHackForAndroidTV = 127,
104*3f982cf4SFabien Sanglard   kVideoHackForAndroidTV = 96,
105*3f982cf4SFabien Sanglard };
106*3f982cf4SFabien Sanglard 
107*3f982cf4SFabien Sanglard // Setting |use_android_rtp_hack| to true means that we match the legacy Chrome
108*3f982cf4SFabien Sanglard // sender's behavior of always sending the audio and video hacks for AndroidTV,
109*3f982cf4SFabien Sanglard // as some legacy android receivers require these.
110*3f982cf4SFabien Sanglard // TODO(issuetracker.google.com/184438154): we need to figure out what receivers
111*3f982cf4SFabien Sanglard // need this still, if any. The hack should be removed when possible.
112*3f982cf4SFabien Sanglard RtpPayloadType GetPayloadType(AudioCodec codec, bool use_android_rtp_hack);
113*3f982cf4SFabien Sanglard RtpPayloadType GetPayloadType(VideoCodec codec, bool use_android_rtp_hack);
114*3f982cf4SFabien Sanglard 
115*3f982cf4SFabien Sanglard // Returns true if the |raw_byte| can be type-casted to a RtpPayloadType, and is
116*3f982cf4SFabien Sanglard // also not RtpPayloadType::kNull. The caller should mask the byte, to select
117*3f982cf4SFabien Sanglard // the lower 7 bits, if applicable.
118*3f982cf4SFabien Sanglard bool IsRtpPayloadType(uint8_t raw_byte);
119*3f982cf4SFabien Sanglard 
120*3f982cf4SFabien Sanglard // Bitmasks to isolate fields within byte 12 of the Cast RTP header.
121*3f982cf4SFabien Sanglard constexpr uint8_t kRtpKeyFrameBitMask = 0b10000000;
122*3f982cf4SFabien Sanglard constexpr uint8_t kRtpHasReferenceFrameIdBitMask = 0b01000000;
123*3f982cf4SFabien Sanglard constexpr uint8_t kRtpExtensionCountMask = 0b00111111;
124*3f982cf4SFabien Sanglard 
125*3f982cf4SFabien Sanglard // Cast extensions. This implementation supports only the Adaptive Latency
126*3f982cf4SFabien Sanglard // extension, and ignores all others:
127*3f982cf4SFabien Sanglard //
128*3f982cf4SFabien Sanglard //  0                   1                   2                   3
129*3f982cf4SFabien Sanglard //  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
130*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
131*3f982cf4SFabien Sanglard // |  TYPE = 1 | Ext data SIZE = 2 |Playout Delay (unsigned millis)|
132*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
133*3f982cf4SFabien Sanglard //
134*3f982cf4SFabien Sanglard // The Adaptive Latency extension permits changing the fixed end-to-end playout
135*3f982cf4SFabien Sanglard // delay of a single RTP stream.
136*3f982cf4SFabien Sanglard constexpr uint8_t kAdaptiveLatencyRtpExtensionType = 1;
137*3f982cf4SFabien Sanglard constexpr int kNumExtensionDataSizeFieldBits = 10;
138*3f982cf4SFabien Sanglard 
139*3f982cf4SFabien Sanglard // RTCP Common Header:
140*3f982cf4SFabien Sanglard //
141*3f982cf4SFabien Sanglard //  0                   1                   2                   3
142*3f982cf4SFabien Sanglard //  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
143*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144*3f982cf4SFabien Sanglard // |V=2|P|RC/Subtyp|  Packet Type  |            Length             |
145*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
146*3f982cf4SFabien Sanglard constexpr int kRtcpCommonHeaderSize = 4;
147*3f982cf4SFabien Sanglard // All RTCP packets must carry the version 2 flag and not use padding.
148*3f982cf4SFabien Sanglard constexpr uint8_t kRtcpRequiredVersionAndPaddingBits = 0b100;
149*3f982cf4SFabien Sanglard constexpr int kRtcpReportCountFieldNumBits = 5;
150*3f982cf4SFabien Sanglard 
151*3f982cf4SFabien Sanglard // https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml
152*3f982cf4SFabien Sanglard enum class RtcpPacketType : uint8_t {
153*3f982cf4SFabien Sanglard   kNull = 0,
154*3f982cf4SFabien Sanglard 
155*3f982cf4SFabien Sanglard   kSenderReport = 200,
156*3f982cf4SFabien Sanglard   kReceiverReport = 201,
157*3f982cf4SFabien Sanglard   kSourceDescription = 202,
158*3f982cf4SFabien Sanglard   kApplicationDefined = 204,
159*3f982cf4SFabien Sanglard   kPayloadSpecific = 206,
160*3f982cf4SFabien Sanglard   kExtendedReports = 207,
161*3f982cf4SFabien Sanglard };
162*3f982cf4SFabien Sanglard 
163*3f982cf4SFabien Sanglard // Returns true if the |raw_byte| can be type-casted to a RtcpPacketType, and is
164*3f982cf4SFabien Sanglard // also not RtcpPacketType::kNull.
165*3f982cf4SFabien Sanglard bool IsRtcpPacketType(uint8_t raw_byte);
166*3f982cf4SFabien Sanglard 
167*3f982cf4SFabien Sanglard // Supported subtype values in the RTCP Common Header when the packet type is
168*3f982cf4SFabien Sanglard // kApplicationDefined or kPayloadSpecific.
169*3f982cf4SFabien Sanglard enum class RtcpSubtype : uint8_t {
170*3f982cf4SFabien Sanglard   kNull = 0,
171*3f982cf4SFabien Sanglard 
172*3f982cf4SFabien Sanglard   kPictureLossIndicator = 1,
173*3f982cf4SFabien Sanglard   kReceiverLog = 2,
174*3f982cf4SFabien Sanglard   kFeedback = 15,
175*3f982cf4SFabien Sanglard };
176*3f982cf4SFabien Sanglard 
177*3f982cf4SFabien Sanglard // RTCP Sender Report:
178*3f982cf4SFabien Sanglard //
179*3f982cf4SFabien Sanglard //  0                   1                   2                   3
180*3f982cf4SFabien Sanglard //  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
181*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
182*3f982cf4SFabien Sanglard // |                        SSRC of Sender                         |
183*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
184*3f982cf4SFabien Sanglard // |                                                               |
185*3f982cf4SFabien Sanglard // |                         NTP Timestamp                         |
186*3f982cf4SFabien Sanglard // |                                                               |
187*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
188*3f982cf4SFabien Sanglard // |                         RTP Timestamp                         |
189*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
190*3f982cf4SFabien Sanglard // |                     Sender's Packet Count                     |
191*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
192*3f982cf4SFabien Sanglard // |                     Sender's Octet Count                      |
193*3f982cf4SFabien Sanglard // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
194*3f982cf4SFabien Sanglard //        ...Followed by zero or more "Report Blocks"...
195*3f982cf4SFabien Sanglard constexpr int kRtcpSenderReportSize = 24;
196*3f982cf4SFabien Sanglard 
197*3f982cf4SFabien Sanglard // RTCP Receiver Report:
198*3f982cf4SFabien Sanglard //
199*3f982cf4SFabien Sanglard //  0                   1                   2                   3
200*3f982cf4SFabien Sanglard //  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
201*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
202*3f982cf4SFabien Sanglard // |                       SSRC of Receiver                        |
203*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
204*3f982cf4SFabien Sanglard //        ...Followed by zero or more "Report Blocks"...
205*3f982cf4SFabien Sanglard constexpr int kRtcpReceiverReportSize = 4;
206*3f982cf4SFabien Sanglard 
207*3f982cf4SFabien Sanglard // RTCP Report Block. For Cast Streaming, zero or one of these accompanies a
208*3f982cf4SFabien Sanglard // Sender or Receiver Report, which is different than the RTCP spec (which
209*3f982cf4SFabien Sanglard // allows zero or more).
210*3f982cf4SFabien Sanglard //
211*3f982cf4SFabien Sanglard //  0                   1                   2                   3
212*3f982cf4SFabien Sanglard //  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
213*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
214*3f982cf4SFabien Sanglard // |                           "To" SSRC                           |
215*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
216*3f982cf4SFabien Sanglard // | Fraction Lost |       Cumulative Number of Packets Lost       |
217*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
218*3f982cf4SFabien Sanglard // |      [32-bit extended] Highest Sequence Number Received       |
219*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
220*3f982cf4SFabien Sanglard // | Interarrival Jitter Mean Absolute Deviation (in RTP Timebase) |
221*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
222*3f982cf4SFabien Sanglard // |    Middle 32-bits of NTP Timestamp from last Sender Report    |
223*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
224*3f982cf4SFabien Sanglard // |     Delay since last Sender Report (1/65536 sec timebase)     |
225*3f982cf4SFabien Sanglard // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
226*3f982cf4SFabien Sanglard constexpr int kRtcpReportBlockSize = 24;
227*3f982cf4SFabien Sanglard constexpr int kRtcpCumulativePacketsFieldNumBits = 24;
228*3f982cf4SFabien Sanglard 
229*3f982cf4SFabien Sanglard // Cast Feedback Message:
230*3f982cf4SFabien Sanglard //
231*3f982cf4SFabien Sanglard //  0                   1                   2                   3
232*3f982cf4SFabien Sanglard //  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
233*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
234*3f982cf4SFabien Sanglard // |                       SSRC of Receiver                        |
235*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
236*3f982cf4SFabien Sanglard // |                        SSRC of Sender                         |
237*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
238*3f982cf4SFabien Sanglard // |               Unique identifier 'C' 'A' 'S' 'T'               |
239*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
240*3f982cf4SFabien Sanglard // | CkPt Frame ID | # Loss Fields | Current Playout Delay (msec)  |
241*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
242*3f982cf4SFabien Sanglard constexpr int kRtcpFeedbackHeaderSize = 16;
243*3f982cf4SFabien Sanglard constexpr uint32_t kRtcpCastIdentifierWord =
244*3f982cf4SFabien Sanglard     (uint32_t{'C'} << 24) | (uint32_t{'A'} << 16) | (uint32_t{'S'} << 8) |
245*3f982cf4SFabien Sanglard     uint32_t{'T'};
246*3f982cf4SFabien Sanglard //
247*3f982cf4SFabien Sanglard // "Checkpoint Frame ID" indicates that all frames prior to and including this
248*3f982cf4SFabien Sanglard // one have been fully received. Unfortunately, the Frame ID is truncated to its
249*3f982cf4SFabien Sanglard // lower 8 bits in the packet, and 8 bits is not really enough: If a RTCP packet
250*3f982cf4SFabien Sanglard // is received very late (e.g., more than 1.2 seconds late for 100 FPS audio),
251*3f982cf4SFabien Sanglard // the Checkpoint Frame ID here will be mis-interpreted as representing a
252*3f982cf4SFabien Sanglard // higher-numbered frame than what was intended. This could make the sender's
253*3f982cf4SFabien Sanglard // tracking of "completely received" frames inconsistent, and Cast Streaming
254*3f982cf4SFabien Sanglard // would live-lock. However, this design issue has been baked into the spec and
255*3f982cf4SFabien Sanglard // millions of deployments over several years, and so there's no changing it
256*3f982cf4SFabien Sanglard // now. See kMaxUnackedFrames in constants.h.
257*3f982cf4SFabien Sanglard //
258*3f982cf4SFabien Sanglard // "# Loss fields" indicates the number of packet-level NACK words, 0 to 255:
259*3f982cf4SFabien Sanglard //
260*3f982cf4SFabien Sanglard //  0                   1                   2                   3
261*3f982cf4SFabien Sanglard //  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
262*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
263*3f982cf4SFabien Sanglard // | w/in Frame ID | Lost Frame Packet ID          | PID BitVector |
264*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265*3f982cf4SFabien Sanglard constexpr int kRtcpFeedbackLossFieldSize = 4;
266*3f982cf4SFabien Sanglard //
267*3f982cf4SFabien Sanglard // "Within Frame ID" is a truncated-to-8-bits frame ID field and, when
268*3f982cf4SFabien Sanglard // bit-expanded should always be interpreted to represent a value greater than
269*3f982cf4SFabien Sanglard // the Checkpoint Frame ID. "Lost Frame Packet ID" is either a specific packet
270*3f982cf4SFabien Sanglard // (within the frame) that has not been received, or kAllPacketsLost to indicate
271*3f982cf4SFabien Sanglard // none the packets for the frame have been received yet. In the former case,
272*3f982cf4SFabien Sanglard // "PID Bit Vector" then represents which of the next 8 packets are also
273*3f982cf4SFabien Sanglard // missing.
274*3f982cf4SFabien Sanglard //
275*3f982cf4SFabien Sanglard // Finally, all of the above is optionally followed by a frame-level ACK bit
276*3f982cf4SFabien Sanglard // vector:
277*3f982cf4SFabien Sanglard //
278*3f982cf4SFabien Sanglard //  0                   1                   2                   3
279*3f982cf4SFabien Sanglard //  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
280*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
281*3f982cf4SFabien Sanglard // |               Unique identifier 'C' 'S' 'T' '2'               |
282*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
283*3f982cf4SFabien Sanglard // |Feedback Count | # BVectOctets | ACK BitVect (2 to 254 bytes)...
284*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ → zero-padded to word boundary
285*3f982cf4SFabien Sanglard constexpr int kRtcpFeedbackAckHeaderSize = 6;
286*3f982cf4SFabien Sanglard constexpr uint32_t kRtcpCst2IdentifierWord =
287*3f982cf4SFabien Sanglard     (uint32_t{'C'} << 24) | (uint32_t{'S'} << 16) | (uint32_t{'T'} << 8) |
288*3f982cf4SFabien Sanglard     uint32_t{'2'};
289*3f982cf4SFabien Sanglard constexpr int kRtcpMinAckBitVectorOctets = 2;
290*3f982cf4SFabien Sanglard constexpr int kRtcpMaxAckBitVectorOctets = 254;
291*3f982cf4SFabien Sanglard //
292*3f982cf4SFabien Sanglard // "Feedback Count" is a wrap-around counter indicating the number of Cast
293*3f982cf4SFabien Sanglard // Feedbacks that have been sent before this one. "# Bit Vector Octets"
294*3f982cf4SFabien Sanglard // indicates the number of bytes of ACK bit vector following. Cast RTCP
295*3f982cf4SFabien Sanglard // alignment/padding requirements (to 4-byte boundaries) dictates the following
296*3f982cf4SFabien Sanglard // rules for generating the ACK bit vector:
297*3f982cf4SFabien Sanglard //
298*3f982cf4SFabien Sanglard //   1. There must be at least 2 bytes of ACK bit vector, if only to pad the 6
299*3f982cf4SFabien Sanglard //      byte header with two more bytes.
300*3f982cf4SFabien Sanglard //   2. If more than 2 bytes are needed, they must be added 4 at a time to
301*3f982cf4SFabien Sanglard //      maintain the 4-byte alignment of the overall RTCP packet.
302*3f982cf4SFabien Sanglard //   3. The total number of octets may not exceed 255; but, because of #2, 254
303*3f982cf4SFabien Sanglard //      is effectively the limit.
304*3f982cf4SFabien Sanglard //   4. The first bit in the first octet represents "Checkpoint Frame ID" plus
305*3f982cf4SFabien Sanglard //      two. "Plus two" and not "plus one" because otherwise the "Checkpoint
306*3f982cf4SFabien Sanglard //      Frame ID" should have been a greater value!
307*3f982cf4SFabien Sanglard 
308*3f982cf4SFabien Sanglard // RTCP Extended Report:
309*3f982cf4SFabien Sanglard //
310*3f982cf4SFabien Sanglard //  0                   1                   2                   3
311*3f982cf4SFabien Sanglard //  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
312*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
313*3f982cf4SFabien Sanglard // |                     SSRC of Report Author                     |
314*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
315*3f982cf4SFabien Sanglard constexpr int kRtcpExtendedReportHeaderSize = 4;
316*3f982cf4SFabien Sanglard //
317*3f982cf4SFabien Sanglard // ...followed by zero or more Blocks:
318*3f982cf4SFabien Sanglard //
319*3f982cf4SFabien Sanglard //  0                   1                   2                   3
320*3f982cf4SFabien Sanglard //  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
321*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
322*3f982cf4SFabien Sanglard // |  Block Type   | Reserved = 0  |       Block Length            |
323*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
324*3f982cf4SFabien Sanglard // |           ..."Block Length" words of report data...           |
325*3f982cf4SFabien Sanglard // +                                                               +
326*3f982cf4SFabien Sanglard // +                                                               +
327*3f982cf4SFabien Sanglard constexpr int kRtcpExtendedReportBlockHeaderSize = 4;
328*3f982cf4SFabien Sanglard //
329*3f982cf4SFabien Sanglard // Cast Streaming only uses Receiver Reference Time Reports:
330*3f982cf4SFabien Sanglard // https://tools.ietf.org/html/rfc3611#section-4.4. So, the entire block would
331*3f982cf4SFabien Sanglard // be:
332*3f982cf4SFabien Sanglard //
333*3f982cf4SFabien Sanglard //  0                   1                   2                   3
334*3f982cf4SFabien Sanglard //  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
335*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
336*3f982cf4SFabien Sanglard // | Block Type=4  | Reserved = 0  |       Block Length = 2        |
337*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
338*3f982cf4SFabien Sanglard // |                         NTP Timestamp                         |
339*3f982cf4SFabien Sanglard // |                                                               |
340*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
341*3f982cf4SFabien Sanglard constexpr uint8_t kRtcpReceiverReferenceTimeReportBlockType = 4;
342*3f982cf4SFabien Sanglard constexpr int kRtcpReceiverReferenceTimeReportBlockSize = 8;
343*3f982cf4SFabien Sanglard 
344*3f982cf4SFabien Sanglard // Cast Picture Loss Indicator Message:
345*3f982cf4SFabien Sanglard //
346*3f982cf4SFabien Sanglard //  0                   1                   2                   3
347*3f982cf4SFabien Sanglard //  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
348*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
349*3f982cf4SFabien Sanglard // |                       SSRC of Receiver                        |
350*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
351*3f982cf4SFabien Sanglard // |                        SSRC of Sender                         |
352*3f982cf4SFabien Sanglard // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
353*3f982cf4SFabien Sanglard constexpr int kRtcpPictureLossIndicatorHeaderSize = 8;
354*3f982cf4SFabien Sanglard 
355*3f982cf4SFabien Sanglard }  // namespace cast
356*3f982cf4SFabien Sanglard }  // namespace openscreen
357*3f982cf4SFabien Sanglard 
358*3f982cf4SFabien Sanglard #endif  // CAST_STREAMING_RTP_DEFINES_H_
359