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