1use bytes::{Buf, BufMut, Bytes, BytesMut};
2
3use crate::InvalidInput;
4
5#[repr(packed)]
7struct RawRtpHeader {
8 options: u16,
9 sequence_number: u16,
10 timestamp: u32,
11 ssrc: u32,
12}
13
14#[derive(Clone)]
16pub struct RtpHeader {
17 options: u16,
18 sequence_number: u16,
19 timestamp: u32,
20 ssrc: u32,
21 csrcs: Vec<u32>,
22 extension: Option<RtpHeaderExtension>,
23}
24
25impl RtpHeader {
26 #[inline]
28 pub const fn new() -> Self {
29 Self {
30 options: 2 << 14,
31 sequence_number: 0,
32 timestamp: 0,
33 ssrc: 0,
34 csrcs: Vec::new(),
35 extension: None,
36 }
37 }
38
39 pub fn decode(data: &mut Bytes) -> Result<Self, InvalidInput> {
41 let mut buffer = data.clone();
42
43 if buffer.len() < std::mem::size_of::<RawRtpHeader>() {
44 return Err(InvalidInput);
45 }
46
47 let ptr = buffer.as_ptr() as *const RawRtpHeader;
48 let raw = unsafe { &*ptr };
49
50 let mut res = Self {
51 options: u16::from_be(raw.options),
52 sequence_number: u16::from_be(raw.sequence_number),
53 timestamp: u32::from_be(raw.timestamp),
54 ssrc: u32::from_be(raw.ssrc),
55 csrcs: Vec::new(),
56 extension: None,
57 };
58
59 buffer.advance(std::mem::size_of::<RawRtpHeader>());
60
61 if (res.options >> 14) != 2 {
62 return Err(InvalidInput);
63 }
64
65 let csrc_count = ((res.options >> 8) & 0xf) as usize;
66
67 if buffer.len() < (csrc_count << 2) {
68 return Err(InvalidInput);
69 }
70
71 res.csrcs = Vec::with_capacity(csrc_count);
72
73 for _ in 0..csrc_count {
74 res.csrcs.push(buffer.get_u32());
75 }
76
77 if (res.options & 0x1000) != 0 {
78 res.extension = Some(RtpHeaderExtension::decode(&mut buffer)?);
79 }
80
81 *data = buffer;
82
83 Ok(res)
84 }
85
86 pub fn encode(&self, buf: &mut BytesMut) {
88 buf.reserve(self.raw_size());
89
90 let raw = RawRtpHeader {
91 options: self.options.to_be(),
92 sequence_number: self.sequence_number.to_be(),
93 timestamp: self.timestamp.to_be(),
94 ssrc: self.ssrc.to_be(),
95 };
96
97 let ptr = &raw as *const _ as *const u8;
98
99 let data = unsafe { std::slice::from_raw_parts(ptr, std::mem::size_of::<RawRtpHeader>()) };
100
101 buf.extend_from_slice(data);
102
103 for csrc in &self.csrcs {
104 buf.put_u32(*csrc);
105 }
106
107 if let Some(extension) = self.extension.as_ref() {
108 extension.encode(buf);
109 }
110 }
111
112 #[inline]
114 pub fn padding(&self) -> bool {
115 (self.options & 0x2000) != 0
116 }
117
118 #[inline]
120 pub fn with_padding(mut self, padding: bool) -> Self {
121 self.options &= !0x2000;
122 self.options |= (padding as u16) << 13;
123 self
124 }
125
126 #[inline]
128 pub fn extension(&self) -> Option<&RtpHeaderExtension> {
129 self.extension.as_ref()
130 }
131
132 #[inline]
134 pub fn with_extension(mut self, extension: Option<RtpHeaderExtension>) -> Self {
135 self.options &= !0x1000;
136 self.options |= (extension.is_some() as u16) << 12;
137 self.extension = extension;
138 self
139 }
140
141 #[inline]
143 pub fn marker(&self) -> bool {
144 (self.options & 0x0080) != 0
145 }
146
147 #[inline]
149 pub fn with_marker(mut self, marker: bool) -> Self {
150 self.options &= !0x0080;
151 self.options |= (marker as u16) << 7;
152 self
153 }
154
155 #[inline]
159 pub fn payload_type(&self) -> u8 {
160 (self.options & 0x7f) as u8
161 }
162
163 #[inline]
168 pub fn with_payload_type(mut self, payload_type: u8) -> Self {
169 assert!(payload_type < 128);
170
171 self.options &= !0x7f;
172 self.options |= (payload_type & 0x7f) as u16;
173 self
174 }
175
176 #[inline]
178 pub fn sequence_number(&self) -> u16 {
179 self.sequence_number
180 }
181
182 #[inline]
184 pub fn with_sequence_number(mut self, n: u16) -> Self {
185 self.sequence_number = n;
186 self
187 }
188
189 #[inline]
191 pub fn timestamp(&self) -> u32 {
192 self.timestamp
193 }
194
195 #[inline]
197 pub fn with_timestamp(mut self, timestamp: u32) -> Self {
198 self.timestamp = timestamp;
199 self
200 }
201
202 #[inline]
204 pub fn ssrc(&self) -> u32 {
205 self.ssrc
206 }
207
208 #[inline]
210 pub fn with_ssrc(mut self, ssrc: u32) -> Self {
211 self.ssrc = ssrc;
212 self
213 }
214
215 #[inline]
217 pub fn csrcs(&self) -> &[u32] {
218 &self.csrcs
219 }
220
221 #[inline]
226 pub fn with_csrcs<T>(mut self, csrcs: T) -> Self
227 where
228 T: Into<Vec<u32>>,
229 {
230 let csrcs = csrcs.into();
231
232 assert!(csrcs.len() <= 0xf);
233
234 self.csrcs = csrcs;
235 self.options &= !0xf00;
236 self.options |= (self.csrcs.len() as u16) << 8;
237 self
238 }
239
240 #[inline]
242 pub fn raw_size(&self) -> usize {
243 std::mem::size_of::<RawRtpHeader>()
244 + (self.csrcs.len() << 2)
245 + self.extension.as_ref().map(|e| e.raw_size()).unwrap_or(0)
246 }
247}
248
249impl Default for RtpHeader {
250 #[inline]
251 fn default() -> Self {
252 Self::new()
253 }
254}
255
256#[repr(packed)]
258struct RawHeaderExtension {
259 misc: u16,
260 length: u16,
261}
262
263#[derive(Clone)]
265pub struct RtpHeaderExtension {
266 misc: u16,
267 data: Bytes,
268}
269
270impl RtpHeaderExtension {
271 #[inline]
273 pub const fn new() -> Self {
274 Self {
275 misc: 0,
276 data: Bytes::new(),
277 }
278 }
279
280 pub fn decode(data: &mut Bytes) -> Result<Self, InvalidInput> {
282 let mut buffer = data.clone();
283
284 if buffer.len() < std::mem::size_of::<RawHeaderExtension>() {
285 return Err(InvalidInput);
286 }
287
288 let ptr = buffer.as_ptr() as *const RawHeaderExtension;
289 let raw = unsafe { &*ptr };
290
291 let extension_length = (u16::from_be(raw.length) as usize) << 2;
292 let misc = u16::from_be(raw.misc);
293
294 buffer.advance(std::mem::size_of::<RawHeaderExtension>());
295
296 if buffer.len() < extension_length {
297 return Err(InvalidInput);
298 }
299
300 let res = Self {
301 misc,
302 data: buffer.split_to(extension_length),
303 };
304
305 *data = buffer;
306
307 Ok(res)
308 }
309
310 pub fn encode(&self, buf: &mut BytesMut) {
312 buf.reserve(self.raw_size());
313
314 let length = (self.data.len() >> 2) as u16;
315
316 let raw = RawHeaderExtension {
317 misc: self.misc.to_be(),
318 length: length.to_be(),
319 };
320
321 let ptr = &raw as *const _ as *const u8;
322
323 let header =
324 unsafe { std::slice::from_raw_parts(ptr, std::mem::size_of::<RawHeaderExtension>()) };
325
326 buf.extend_from_slice(header);
327 buf.extend_from_slice(&self.data);
328 }
329
330 #[inline]
332 pub fn misc(&self) -> u16 {
333 self.misc
334 }
335
336 #[inline]
338 pub fn with_misc(mut self, misc: u16) -> Self {
339 self.misc = misc;
340 self
341 }
342
343 #[inline]
345 pub fn data(&self) -> &Bytes {
346 &self.data
347 }
348
349 #[inline]
355 pub fn with_data(mut self, data: Bytes) -> Self {
356 assert_eq!(data.len() & 3, 0);
357
358 let words = data.len() >> 2;
359
360 assert!(words <= (u16::MAX as usize));
361
362 self.data = data;
363 self
364 }
365
366 #[inline]
369 pub fn raw_size(&self) -> usize {
370 std::mem::size_of::<RawHeaderExtension>() + self.data.len()
371 }
372}
373
374impl Default for RtpHeaderExtension {
375 #[inline]
376 fn default() -> Self {
377 Self::new()
378 }
379}
380
381#[derive(Clone)]
383pub struct RtpPacket {
384 header: RtpHeader,
385 payload: Bytes,
386}
387
388impl RtpPacket {
389 #[inline]
391 pub const fn new() -> Self {
392 Self {
393 header: RtpHeader::new(),
394 payload: Bytes::new(),
395 }
396 }
397
398 pub fn from_parts(header: RtpHeader, payload: Bytes) -> Result<Self, InvalidInput> {
400 if header.padding() {
401 let padding_len = payload.last().copied().ok_or(InvalidInput)? as usize;
402
403 if padding_len == 0 || payload.len() < padding_len {
404 return Err(InvalidInput);
405 }
406 }
407
408 let res = Self { header, payload };
409
410 Ok(res)
411 }
412
413 #[inline]
415 pub fn deconstruct(self) -> (RtpHeader, Bytes) {
416 (self.header, self.payload)
417 }
418
419 pub fn decode(mut frame: Bytes) -> Result<Self, InvalidInput> {
421 let header = RtpHeader::decode(&mut frame)?;
422
423 let payload = frame;
424
425 Self::from_parts(header, payload)
426 }
427
428 pub fn encode(&self, buf: &mut BytesMut) {
430 buf.reserve(self.raw_size());
431
432 self.header.encode(buf);
433
434 buf.extend_from_slice(&self.payload);
435 }
436
437 #[inline]
439 pub fn header(&self) -> &RtpHeader {
440 &self.header
441 }
442
443 #[inline]
445 pub fn marker(&self) -> bool {
446 self.header.marker()
447 }
448
449 #[inline]
451 pub fn with_marker(mut self, marker: bool) -> Self {
452 self.header = self.header.with_marker(marker);
453 self
454 }
455
456 #[inline]
460 pub fn payload_type(&self) -> u8 {
461 self.header.payload_type()
462 }
463
464 #[inline]
469 pub fn with_payload_type(mut self, payload_type: u8) -> Self {
470 self.header = self.header.with_payload_type(payload_type);
471 self
472 }
473
474 #[inline]
476 pub fn sequence_number(&self) -> u16 {
477 self.header.sequence_number()
478 }
479
480 #[inline]
482 pub fn with_sequence_number(mut self, sequence_number: u16) -> Self {
483 self.header = self.header.with_sequence_number(sequence_number);
484 self
485 }
486
487 #[inline]
489 pub fn timestamp(&self) -> u32 {
490 self.header.timestamp()
491 }
492
493 #[inline]
495 pub fn with_timestamp(mut self, timestamp: u32) -> Self {
496 self.header = self.header.with_timestamp(timestamp);
497 self
498 }
499
500 #[inline]
502 pub fn ssrc(&self) -> u32 {
503 self.header.ssrc()
504 }
505
506 #[inline]
508 pub fn with_ssrc(mut self, ssrc: u32) -> Self {
509 self.header = self.header.with_ssrc(ssrc);
510 self
511 }
512
513 #[inline]
515 pub fn csrcs(&self) -> &[u32] {
516 self.header.csrcs()
517 }
518
519 #[inline]
524 pub fn with_csrcs<T>(mut self, csrcs: T) -> Self
525 where
526 T: Into<Vec<u32>>,
527 {
528 self.header = self.header.with_csrcs(csrcs);
529 self
530 }
531
532 #[inline]
536 pub fn padding(&self) -> u8 {
537 if self.header.padding() {
538 *self.payload.last().unwrap()
539 } else {
540 0
541 }
542 }
543
544 #[inline]
546 pub fn payload(&self) -> &Bytes {
547 &self.payload
548 }
549
550 #[inline]
552 pub fn stripped_payload(&self) -> Bytes {
553 let payload_len = self.payload.len();
554 let padding_len = self.padding() as usize;
555
556 let len = payload_len - padding_len;
557
558 self.payload.slice(..len)
559 }
560
561 #[inline]
566 pub fn with_payload(mut self, payload: Bytes, padding: u8) -> Self {
567 if padding > 0 {
568 let len = payload.len() + (padding as usize);
569
570 let mut buffer = BytesMut::with_capacity(len);
571
572 buffer.extend_from_slice(&payload);
573 buffer.resize(len, 0);
574
575 buffer[len - 1] = padding;
576
577 self.header = self.header.with_padding(true);
578 self.payload = buffer.freeze();
579 } else {
580 self.header = self.header.with_padding(false);
581 self.payload = payload;
582 }
583
584 self
585 }
586
587 #[inline]
594 pub fn with_padded_payload(mut self, payload: Bytes) -> Self {
595 let padding_len = payload.last().copied().expect("empty payload") as usize;
596
597 assert!(padding_len > 0 && payload.len() >= padding_len);
598
599 self.header = self.header.with_padding(true);
600 self.payload = payload;
601 self
602 }
603
604 #[inline]
606 pub fn raw_size(&self) -> usize {
607 self.header.raw_size() + self.payload.len()
608 }
609}
610
611impl Default for RtpPacket {
612 #[inline]
613 fn default() -> Self {
614 Self::new()
615 }
616}