1use std::marker::PhantomData;
4
5use crate::RtpPacket;
6
7#[derive(Debug, PartialEq, Eq, thiserror::Error)]
9pub enum RtpWriteError {
10 #[error("Output buffer is not large enough to fit the resulting buffer. Requested size: {}", .0)]
13 OutputTooSmall(usize),
14 #[error("Invalid payload type {}", .0)]
16 InvalidPayloadType(u8),
17 #[error("Packet is too large")]
19 PacketTooLarge,
20 #[error("Too many contribution sources: {}", .0)]
23 TooManyContributionSources(usize),
24 #[error("Extension data is not padded to a multiple of 4")]
26 ExtensionDataNotPadded,
27 #[error("Value used for padding is invalid")]
29 InvalidPadding,
30}
31
32#[derive(Debug)]
34#[must_use = "The builder must be built to be used"]
35pub struct RtpPacketBuilder<P: PayloadLength, E: PayloadLength> {
36 padding: Option<u8>,
37 csrcs: smallvec::SmallVec<[u32; 15]>,
38 marker_bit: bool,
39 payload_type: u8,
40 sequence_number: u16,
41 timestamp: u32,
42 ssrc: u32,
43 extension: Option<(u16, E)>,
44 payloads: smallvec::SmallVec<[P; 16]>,
45}
46
47impl<P: PayloadLength, E: PayloadLength> Default for RtpPacketBuilder<P, E> {
48 fn default() -> Self {
49 Self::new()
50 }
51}
52
53impl<P: PayloadLength, E: PayloadLength> RtpPacketBuilder<P, E> {
54 pub fn new() -> RtpPacketBuilder<P, E> {
56 Self {
57 padding: None,
58 csrcs: smallvec::smallvec![],
59 marker_bit: false,
60 payload_type: 0xff,
62 sequence_number: 0,
63 timestamp: 0,
64 ssrc: 0,
65 extension: None,
66 payloads: smallvec::SmallVec::new(),
67 }
68 }
69
70 pub fn padding(mut self, padding: u8) -> Self {
72 self.padding = Some(padding);
73 self
74 }
75
76 pub fn maybe_padding(mut self, padding: Option<u8>) -> Self {
78 self.padding = padding;
79 self
80 }
81
82 pub fn add_csrc(mut self, csrc: u32) -> Self {
84 self.csrcs.push(csrc);
85 self
86 }
87
88 pub fn clear_csrcs(mut self) -> Self {
90 self.csrcs.clear();
91 self
92 }
93
94 #[deprecated = "Use `marker_bit()` instead"]
96 pub fn marker(self, marker: bool) -> Self {
97 self.marker_bit(marker)
98 }
99
100 pub fn marker_bit(mut self, marker_bit: bool) -> Self {
102 self.marker_bit = marker_bit;
103 self
104 }
105
106 pub fn payload_type(mut self, pt: u8) -> Self {
108 self.payload_type = pt;
109 self
110 }
111
112 pub fn sequence_number(mut self, sequence: u16) -> Self {
114 self.sequence_number = sequence;
115 self
116 }
117
118 pub fn timestamp(mut self, timestamp: u32) -> Self {
120 self.timestamp = timestamp;
121 self
122 }
123
124 pub fn ssrc(mut self, ssrc: u32) -> Self {
126 self.ssrc = ssrc;
127 self
128 }
129
130 pub fn extension(mut self, extension_id: u16, extension_data: E) -> Self {
132 self.extension = Some((extension_id, extension_data));
133 self
134 }
135
136 pub fn clear_extension(mut self) -> Self {
138 self.extension = None;
139 self
140 }
141
142 pub fn payload(mut self, payload: P) -> Self {
147 self.payloads.push(payload);
148 self
149 }
150
151 pub fn clear_payloads(mut self) -> Self {
153 self.payloads.clear();
154 self
155 }
156
157 pub fn calculate_size(&self) -> Result<usize, RtpWriteError> {
159 let payload_len = self.payloads.iter().map(|p| p.len()).sum::<usize>();
160 let extension_len = if let Some((_ext_id, ext_data)) = self.extension.as_ref() {
161 if ext_data.len() > u16::MAX as usize {
162 return Err(RtpWriteError::PacketTooLarge);
163 }
164 if ext_data.len() % 4 != 0 {
165 return Err(RtpWriteError::ExtensionDataNotPadded);
166 }
167 4 + ext_data.len()
168 } else {
169 0
170 };
171 let mut size = RtpPacket::MIN_RTP_PACKET_LEN;
172 size += self.csrcs.len() * 4;
173 size += extension_len;
174 size += payload_len;
175 if let Some(padding) = self.padding {
176 size += padding as usize;
177 }
178 Ok(size)
179 }
180
181 fn write_header_into(&self, buf: &mut [u8]) -> usize {
182 let mut byte = 0x80; if self.padding.is_some() {
184 byte |= 0x20;
185 }
186 if self.extension.is_some() {
187 byte |= 0x10;
188 }
189 byte |= (self.csrcs.len() as u8) & 0x0f;
190 buf[0] = byte;
191
192 let mut byte = self.payload_type & 0x7f;
193 if self.marker_bit {
194 byte |= 0x80;
195 }
196 buf[1] = byte;
197
198 buf[2] = (self.sequence_number >> 8) as u8;
199 buf[3] = (self.sequence_number & 0xff) as u8;
200
201 buf[4] = (self.timestamp >> 24) as u8;
202 buf[5] = ((self.timestamp >> 16) & 0xff) as u8;
203 buf[6] = ((self.timestamp >> 8) & 0xff) as u8;
204 buf[7] = (self.timestamp & 0xff) as u8;
205
206 buf[8] = (self.ssrc >> 24) as u8;
207 buf[9] = ((self.ssrc >> 16) & 0xff) as u8;
208 buf[10] = ((self.ssrc >> 8) & 0xff) as u8;
209 buf[11] = (self.ssrc & 0xff) as u8;
210
211 RtpPacket::MIN_RTP_PACKET_LEN
212 }
213
214 fn write_preconditions(&self) -> Result<usize, RtpWriteError> {
215 if self.payload_type > 0x7f {
216 return Err(RtpWriteError::InvalidPayloadType(self.payload_type));
217 }
218 if self.csrcs.len() > RtpPacket::MAX_N_CSRCS {
219 return Err(RtpWriteError::TooManyContributionSources(self.csrcs.len()));
220 }
221
222 if let Some(padding) = self.padding {
223 if padding == 0 {
224 return Err(RtpWriteError::InvalidPadding);
225 }
226 }
227
228 self.calculate_size()
229 }
230
231 pub fn write_unchecked<O>(
233 &self,
234 writer: &mut impl RtpPacketWriter<Payload = P, Extension = E, Output = O>,
235 ) -> O {
236 let mut hdr = [0; RtpPacket::MIN_RTP_PACKET_LEN];
237 self.write_header_into(&mut hdr);
238 writer.push(hdr.as_ref());
239
240 for csrc in self.csrcs.iter() {
241 writer.push(csrc.to_be_bytes().as_ref());
242 }
243
244 if let Some((ext_id, ext_data)) = self.extension.as_ref() {
245 writer.push(ext_id.to_be_bytes().as_ref());
246 writer.push(((ext_data.len() / 4) as u16).to_be_bytes().as_ref());
247 writer.push_extension(ext_data);
248 }
249
250 for payload in self.payloads.iter() {
251 writer.push_payload(payload);
252 }
253
254 if let Some(padding) = self.padding {
255 writer.padding(padding);
256 }
257
258 writer.finish()
259 }
260
261 pub fn write<O>(
263 &self,
264 writer: &mut impl RtpPacketWriter<Payload = P, Extension = E, Output = O>,
265 ) -> Result<O, RtpWriteError> {
266 let len = self.write_preconditions()?;
267 if let Some(max_size) = writer.max_size() {
268 if max_size < len {
269 return Err(RtpWriteError::OutputTooSmall(len));
270 }
271 }
272
273 writer.reserve(len);
274 Ok(self.write_unchecked(writer))
275 }
276}
277
278impl<'a, 'b> RtpPacketBuilder<&'a [u8], &'b [u8]> {
279 pub fn write_into_unchecked(&self, buf: &mut [u8]) -> usize {
282 let mut writer = RtpPacketWriterMutSlice::new(buf);
283 self.write_unchecked(&mut writer)
284 }
285
286 pub fn write_into(&self, buf: &mut [u8]) -> Result<usize, RtpWriteError> {
289 let mut writer = RtpPacketWriterMutSlice::new(buf);
290 self.write(&mut writer)
291 }
292
293 pub fn write_into_vec_unchecked(&self, buf: &mut Vec<u8>) {
296 let mut writer = RtpPacketWriterMutVec::new(buf);
297 self.write_unchecked(&mut writer)
298 }
299
300 pub fn write_into_vec(&self, buf: &mut Vec<u8>) -> Result<(), RtpWriteError> {
302 let mut writer = RtpPacketWriterMutVec::new(buf);
303 self.write(&mut writer)
304 }
305
306 pub fn write_vec_unchecked(&self) -> Vec<u8> {
308 let mut writer = RtpPacketWriterVec::default();
309 self.write_unchecked(&mut writer)
310 }
311
312 pub fn write_vec(&self) -> Result<Vec<u8>, RtpWriteError> {
314 let mut writer = RtpPacketWriterVec::default();
315 self.write(&mut writer)
316 }
317}
318
319pub trait PayloadLength {
321 fn len(&self) -> usize;
323 fn is_empty(&self) -> bool {
325 self.len() != 0
326 }
327}
328
329pub trait RtpPacketWriter {
331 type Output;
333 type Payload: PayloadLength;
335 type Extension: PayloadLength;
337
338 fn reserve(&mut self, _size: usize) {}
341
342 fn max_size(&self) -> Option<usize> {
345 None
346 }
347
348 fn push(&mut self, data: &[u8]);
350
351 fn push_extension(&mut self, extension_data: &Self::Extension);
354
355 fn push_payload(&mut self, payload: &Self::Payload);
358
359 fn padding(&mut self, size: u8);
365
366 fn finish(&mut self) -> Self::Output;
369}
370
371impl<T> PayloadLength for &[T] {
372 fn len(&self) -> usize {
373 (self as &[T]).len()
374 }
375}
376
377impl<T> PayloadLength for Vec<T> {
378 fn len(&self) -> usize {
379 (self as &Vec<T>).len()
380 }
381}
382
383impl<T, const N: usize> PayloadLength for [T; N] {
384 fn len(&self) -> usize {
385 self.as_slice().len()
386 }
387}
388
389impl<T, const N: usize> PayloadLength for &[T; N] {
390 fn len(&self) -> usize {
391 self.as_slice().len()
392 }
393}
394
395#[derive(Default, Debug)]
397pub struct RtpPacketWriterVec<'a, 'b> {
398 output: Vec<u8>,
399 padding: Option<u8>,
400 phantom: PhantomData<(&'a [u8], &'b [u8])>,
401}
402
403impl<'a, 'b> RtpPacketWriter for RtpPacketWriterVec<'a, 'b> {
404 type Output = Vec<u8>;
405 type Payload = &'a [u8];
406 type Extension = &'b [u8];
407
408 fn reserve(&mut self, size: usize) {
409 if self.output.len() < size {
410 self.output.reserve(size - self.output.len());
411 }
412 }
413
414 fn push(&mut self, data: &[u8]) {
415 self.output.extend_from_slice(data)
416 }
417
418 fn push_extension(&mut self, extension_data: &Self::Extension) {
419 self.push(extension_data)
420 }
421
422 fn push_payload(&mut self, data: &Self::Payload) {
423 self.push(data)
424 }
425
426 fn padding(&mut self, size: u8) {
427 self.padding = Some(size);
428 }
429
430 fn finish(&mut self) -> Self::Output {
431 let mut ret = vec![];
432 if let Some(padding) = self.padding.take() {
433 self.output
434 .resize(self.output.len() + padding as usize - 1, 0);
435 self.output.push(padding);
436 }
437 std::mem::swap(&mut ret, &mut self.output);
438 ret
439 }
440}
441
442#[derive(Default, Debug)]
445pub struct RtpPacketWriterMutSlice<'a, 'b, 'c> {
446 output: &'a mut [u8],
447 padding: Option<u8>,
448 write_i: usize,
449 phantom: PhantomData<(&'b [u8], &'c [u8])>,
450}
451
452impl<'a, 'b, 'c> RtpPacketWriterMutSlice<'a, 'b, 'c> {
453 pub fn new(buf: &'a mut [u8]) -> Self {
455 Self {
456 output: buf,
457 padding: None,
458 write_i: 0,
459 phantom: PhantomData,
460 }
461 }
462}
463
464impl<'a, 'b, 'c> std::ops::Deref for RtpPacketWriterMutSlice<'a, 'b, 'c> {
465 type Target = [u8];
466
467 fn deref(&self) -> &Self::Target {
468 self.output
469 }
470}
471
472impl<'a, 'b, 'c> std::ops::DerefMut for RtpPacketWriterMutSlice<'a, 'b, 'c> {
473 fn deref_mut(&mut self) -> &mut Self::Target {
474 self.output
475 }
476}
477
478impl<'a, 'b, 'c> RtpPacketWriter for RtpPacketWriterMutSlice<'a, 'b, 'c> {
479 type Output = usize;
480 type Payload = &'b [u8];
481 type Extension = &'c [u8];
482
483 fn max_size(&self) -> Option<usize> {
484 Some(self.output.len())
485 }
486
487 fn push(&mut self, data: &[u8]) {
488 self.output[self.write_i..self.write_i + data.len()].copy_from_slice(data);
489 self.write_i += data.len();
490 }
491
492 fn push_extension(&mut self, extension_data: &Self::Extension) {
493 self.push(extension_data)
494 }
495
496 fn push_payload(&mut self, data: &Self::Payload) {
497 self.push(data)
498 }
499
500 fn padding(&mut self, size: u8) {
501 self.padding = Some(size);
502 }
503
504 fn finish(&mut self) -> Self::Output {
505 if let Some(padding) = self.padding.take() {
506 if padding > 1 {
507 self.output[self.write_i..self.write_i + padding as usize - 1].fill(0);
508 }
509 self.write_i += padding as usize;
510 self.output[self.write_i - 1] = padding;
511 }
512 let ret = self.write_i;
513 self.write_i = 0;
514 ret
515 }
516}
517
518#[derive(Debug)]
522pub struct RtpPacketWriterMutVec<'a, 'b, 'c> {
523 output: &'a mut Vec<u8>,
524 padding: Option<u8>,
525 phantom: PhantomData<(&'b [u8], &'c [u8])>,
526}
527
528impl<'a, 'b, 'c> RtpPacketWriterMutVec<'a, 'b, 'c> {
529 pub fn new(buf: &'a mut Vec<u8>) -> Self {
531 Self {
532 output: buf,
533 padding: None,
534 phantom: PhantomData,
535 }
536 }
537}
538
539impl<'a, 'b, 'c> std::ops::Deref for RtpPacketWriterMutVec<'a, 'b, 'c> {
540 type Target = Vec<u8>;
541
542 fn deref(&self) -> &Self::Target {
543 self.output
544 }
545}
546
547impl<'a, 'b, 'c> std::ops::DerefMut for RtpPacketWriterMutVec<'a, 'b, 'c> {
548 fn deref_mut(&mut self) -> &mut Self::Target {
549 self.output
550 }
551}
552
553impl<'a, 'b, 'c> RtpPacketWriter for RtpPacketWriterMutVec<'a, 'b, 'c> {
554 type Output = ();
555 type Payload = &'b [u8];
556 type Extension = &'c [u8];
557
558 fn push(&mut self, data: &[u8]) {
559 self.output.extend(data);
560 }
561
562 fn push_extension(&mut self, extension_data: &Self::Extension) {
563 self.push(extension_data)
564 }
565
566 fn push_payload(&mut self, data: &Self::Payload) {
567 self.push(data)
568 }
569
570 fn padding(&mut self, size: u8) {
571 self.padding = Some(size);
572 }
573
574 fn finish(&mut self) -> Self::Output {
575 if let Some(padding) = self.padding.take() {
576 self.output
577 .extend(std::iter::repeat(0).take(padding as usize - 1));
578 self.output.push(padding);
579 }
580 }
581}
582
583#[cfg(test)]
584mod tests {
585 use super::*;
586
587 #[test]
588 fn write_rtp_default() {
589 let mut data = [0; 128];
590 let mut vec = vec![];
591 let builder = RtpPacketBuilder::new().payload_type(96);
592 let size = builder.write_into(&mut data).unwrap();
593 let buf = builder.write_vec().unwrap();
594 builder.write_into_vec(&mut vec).unwrap();
595 drop(builder);
596 let data = &data[..size];
597 assert_eq!(size, buf.len());
598 assert_eq!(size, vec.len());
599 for data in [data, buf.as_ref(), vec.as_ref()] {
600 println!("{data:?}");
601 let rtp = RtpPacket::parse(data).unwrap();
602 assert_eq!(rtp.version(), 2);
603 assert_eq!(rtp.padding(), None);
604 assert_eq!(rtp.n_csrcs(), 0);
605 assert!(!rtp.marker_bit());
606 assert_eq!(rtp.payload_type(), 96);
607 assert_eq!(rtp.sequence_number(), 0x0);
608 assert_eq!(rtp.timestamp(), 0x0);
609 assert_eq!(rtp.ssrc(), 0x0);
610 assert_eq!(rtp.csrc().count(), 0);
611 assert_eq!(rtp.extension(), None);
612 assert_eq!(rtp.payload(), &[]);
613 }
614 }
615
616 #[test]
617 fn write_rtp_header() {
618 let mut data = [0; 128];
619 let mut vec = vec![];
620 let builder = RtpPacketBuilder::new()
621 .payload_type(96)
622 .marker_bit(true)
623 .sequence_number(0x0102)
624 .timestamp(0x03040506)
625 .ssrc(0x0708090a)
626 .add_csrc(0x0b0c0d0e);
627 let size = builder.write_into(&mut data).unwrap();
628 let buf = builder.write_vec().unwrap();
629 builder.write_into_vec(&mut vec).unwrap();
630 drop(builder);
631 let data = &data[..size];
632 assert_eq!(size, buf.len());
633 assert_eq!(size, vec.len());
634 for data in [data, buf.as_ref(), vec.as_ref()] {
635 println!("{data:?}");
636 let rtp = RtpPacket::parse(data).unwrap();
637 assert_eq!(rtp.version(), 2);
638 assert_eq!(rtp.padding(), None);
639 assert_eq!(rtp.n_csrcs(), 1);
640 assert!(rtp.marker_bit());
641 assert_eq!(rtp.payload_type(), 96);
642 assert_eq!(rtp.sequence_number(), 0x0102);
643 assert_eq!(rtp.timestamp(), 0x03040506);
644 assert_eq!(rtp.ssrc(), 0x0708090a);
645 let mut csrc = rtp.csrc();
646 assert_eq!(csrc.next(), Some(0x0b0c0d0e));
647 assert_eq!(csrc.next(), None);
648 assert_eq!(rtp.extension(), None);
649 assert_eq!(rtp.payload(), &[]);
650 }
651 }
652
653 #[test]
654 fn write_rtp_header_multiple_csrcs() {
655 let mut data = [0; 128];
656 let mut vec = vec![];
657 let builder = RtpPacketBuilder::new()
658 .payload_type(96)
659 .add_csrc(0x01020304)
660 .add_csrc(0x05060708);
661 let size = builder.write_into(&mut data).unwrap();
662 let buf = builder.write_vec().unwrap();
663 builder.write_into_vec(&mut vec).unwrap();
664 drop(builder);
665 let data = &data[..size];
666 assert_eq!(size, buf.len());
667 assert_eq!(size, vec.len());
668 for data in [data, buf.as_ref(), vec.as_ref()] {
669 println!("{data:?}");
670 let rtp = RtpPacket::parse(data).unwrap();
671 assert_eq!(rtp.n_csrcs(), 2);
672 let mut csrc = rtp.csrc();
673 assert_eq!(csrc.next(), Some(0x01020304));
674 assert_eq!(csrc.next(), Some(0x05060708));
675 assert_eq!(csrc.next(), None);
676 }
677 }
678
679 #[test]
680 fn write_rtp_multiple_payloads() {
681 let mut data = [0; 128];
682 let mut vec = vec![];
683 let payload_data = [1, 2, 3, 4, 5, 6, 7, 8];
684 let more_payload_data = [9, 10, 11];
685 let builder = RtpPacketBuilder::new()
686 .payload_type(96)
687 .payload(payload_data.as_ref())
688 .payload(more_payload_data.as_ref())
689 .payload(more_payload_data[0..1].as_ref());
690 let size = builder.write_into(&mut data).unwrap();
691 assert_eq!(size, 24);
692 let buf = builder.write_vec().unwrap();
693 builder.write_into_vec(&mut vec).unwrap();
694 drop(builder);
695 let data = &data[..size];
696 assert_eq!(size, buf.len());
697 assert_eq!(size, vec.len());
698 for data in [data, buf.as_ref(), vec.as_ref()] {
699 println!("{data:?}");
700 let rtp = RtpPacket::parse(data).unwrap();
701 assert_eq!(rtp.version(), 2);
702 assert_eq!(rtp.payload_type(), 96);
703 assert_eq!(rtp.payload(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 9]);
704 }
705 }
706
707 #[test]
708 fn write_rtp_extension() {
709 let mut data = [0; 128];
710 let mut vec = vec![];
711 let extension_data = [1, 2, 3, 4, 5, 6, 7, 8];
712 let builder = RtpPacketBuilder::new()
713 .payload_type(96)
714 .marker_bit(true)
715 .sequence_number(0x0102)
716 .timestamp(0x03040506)
717 .ssrc(0x0708090a)
718 .add_csrc(0x0b0c0d0e)
719 .extension(0x9876, extension_data.as_ref());
720 let size = builder.write_into(&mut data).unwrap();
721 let buf = builder.write_vec().unwrap();
722 builder.write_into_vec(&mut vec).unwrap();
723 drop(builder);
724 let data = &data[..size];
725 assert_eq!(size, buf.len());
726 assert_eq!(size, vec.len());
727 for data in [data, buf.as_ref(), vec.as_ref()] {
728 println!("{data:?}");
729 let rtp = RtpPacket::parse(data).unwrap();
730 assert_eq!(rtp.version(), 2);
731 assert_eq!(rtp.padding(), None);
732 assert_eq!(rtp.n_csrcs(), 1);
733 assert!(rtp.marker_bit());
734 assert_eq!(rtp.payload_type(), 96);
735 assert_eq!(rtp.sequence_number(), 0x0102);
736 assert_eq!(rtp.timestamp(), 0x03040506);
737 assert_eq!(rtp.ssrc(), 0x0708090a);
738 let mut csrc = rtp.csrc();
739 assert_eq!(csrc.next(), Some(0x0b0c0d0e));
740 assert_eq!(csrc.next(), None);
741 assert_eq!(rtp.extension(), Some((0x9876, extension_data.as_ref())));
742 assert_eq!(rtp.payload(), &[]);
743 }
744 }
745
746 #[test]
747 fn write_rtp_extension_payload_padding() {
748 let mut data = [0; 128];
749 let mut vec = vec![];
750 let extension_data = [1, 2, 3, 4, 5, 6, 7, 8];
751 let payload_data = [1, 2, 3, 4, 5, 6, 7, 8];
752 let builder = RtpPacketBuilder::new()
753 .payload_type(96)
754 .marker_bit(true)
755 .sequence_number(0x0102)
756 .timestamp(0x03040506)
757 .ssrc(0x0708090a)
758 .add_csrc(0x0b0c0d0e)
759 .extension(0x9876, extension_data.as_ref())
760 .payload(payload_data.as_ref())
761 .padding(7);
762 let size = builder.write_into(&mut data).unwrap();
763 let buf = builder.write_vec().unwrap();
764 builder.write_into_vec(&mut vec).unwrap();
765 drop(builder);
766 let data = &data[..size];
767 assert_eq!(size, buf.len());
768 assert_eq!(size, vec.len());
769 for data in [data, buf.as_ref(), vec.as_ref()] {
770 println!("{data:?}");
771 let rtp = RtpPacket::parse(data).unwrap();
772 assert_eq!(rtp.version(), 2);
773 assert_eq!(rtp.padding(), Some(7));
774 assert_eq!(rtp.n_csrcs(), 1);
775 assert!(rtp.marker_bit());
776 assert_eq!(rtp.payload_type(), 96);
777 assert_eq!(rtp.sequence_number(), 0x0102);
778 assert_eq!(rtp.timestamp(), 0x03040506);
779 assert_eq!(rtp.ssrc(), 0x0708090a);
780 let mut csrc = rtp.csrc();
781 assert_eq!(csrc.next(), Some(0x0b0c0d0e));
782 assert_eq!(csrc.next(), None);
783 assert_eq!(rtp.extension(), Some((0x9876, extension_data.as_ref())));
784 assert_eq!(rtp.payload(), payload_data.as_ref());
785 }
786 }
787
788 #[test]
789 fn write_rtp_invalid_padding() {
790 let mut data = [0; 128];
791 let mut vec = vec![];
792 let builder = RtpPacketBuilder::new().payload_type(96).padding(0);
793 assert_eq!(
794 builder.write_into(&mut data),
795 Err(RtpWriteError::InvalidPadding)
796 );
797 assert_eq!(builder.write_vec(), Err(RtpWriteError::InvalidPadding));
798 assert_eq!(
799 builder.write_into_vec(&mut vec),
800 Err(RtpWriteError::InvalidPadding)
801 );
802 }
803
804 #[test]
805 fn write_rtp_unpadded_extension() {
806 let mut data = [0; 128];
807 let mut vec = vec![];
808 let builder = RtpPacketBuilder::new()
809 .payload_type(96)
810 .extension(0x9876, [1].as_ref());
811 assert_eq!(
812 builder.write_into(&mut data),
813 Err(RtpWriteError::ExtensionDataNotPadded)
814 );
815 assert_eq!(
816 builder.write_vec(),
817 Err(RtpWriteError::ExtensionDataNotPadded)
818 );
819 assert_eq!(
820 builder.write_into_vec(&mut vec),
821 Err(RtpWriteError::ExtensionDataNotPadded)
822 );
823 }
824
825 #[test]
826 fn write_rtp_invalid_payload_type() {
827 let mut data = [0; 128];
828 let mut vec = vec![];
829 let builder = RtpPacketBuilder::new().payload_type(0xFF);
830 assert_eq!(
831 builder.write_into(&mut data),
832 Err(RtpWriteError::InvalidPayloadType(0xFF))
833 );
834 assert_eq!(
835 builder.write_vec(),
836 Err(RtpWriteError::InvalidPayloadType(0xFF))
837 );
838 assert_eq!(
839 builder.write_into_vec(&mut vec),
840 Err(RtpWriteError::InvalidPayloadType(0xFF))
841 );
842 }
843
844 #[test]
845 fn write_rtp_too_many_contributions() {
846 let mut data = [0; 128];
847 let mut vec = vec![];
848 let builder = RtpPacketBuilder::new()
849 .payload_type(96)
850 .add_csrc(1)
851 .add_csrc(2)
852 .add_csrc(3)
853 .add_csrc(4)
854 .add_csrc(5)
855 .add_csrc(6)
856 .add_csrc(7)
857 .add_csrc(8)
858 .add_csrc(9)
859 .add_csrc(10)
860 .add_csrc(11)
861 .add_csrc(12)
862 .add_csrc(13)
863 .add_csrc(14)
864 .add_csrc(15)
865 .add_csrc(16);
866 assert_eq!(
867 builder.write_into(&mut data),
868 Err(RtpWriteError::TooManyContributionSources(16))
869 );
870 assert_eq!(
871 builder.write_vec(),
872 Err(RtpWriteError::TooManyContributionSources(16))
873 );
874 assert_eq!(
875 builder.write_into_vec(&mut vec),
876 Err(RtpWriteError::TooManyContributionSources(16))
877 );
878 }
879
880 #[test]
881 fn write_rtp_extension_too_large() {
882 let mut data = [0; u16::MAX as usize + 128];
883 let mut vec = vec![];
884 let extension_data = [0; u16::MAX as usize + 1];
885 let builder = RtpPacketBuilder::new()
886 .payload_type(96)
887 .extension(0x9876, extension_data.as_ref());
888 assert_eq!(
889 builder.write_into(&mut data),
890 Err(RtpWriteError::PacketTooLarge)
891 );
892 assert_eq!(builder.write_vec(), Err(RtpWriteError::PacketTooLarge));
893 assert_eq!(
894 builder.write_into_vec(&mut vec),
895 Err(RtpWriteError::PacketTooLarge)
896 );
897 }
898
899 #[test]
900 fn write_rtp_output_too_short() {
901 let mut data = [0; 11];
902 assert_eq!(
903 RtpPacketBuilder::new()
904 .payload_type(96)
905 .write_into(&mut data),
906 Err(RtpWriteError::OutputTooSmall(12))
907 );
908 }
909
910 #[test]
911 fn write_rtp_output_too_short_with_csrc() {
912 let mut data = [0; 15];
913 assert_eq!(
914 RtpPacketBuilder::new()
915 .payload_type(96)
916 .add_csrc(1)
917 .write_into(&mut data),
918 Err(RtpWriteError::OutputTooSmall(16))
919 );
920 }
921
922 #[test]
923 fn write_rtp_output_too_short_extension() {
924 let mut data = [0; 15];
925 assert_eq!(
926 RtpPacketBuilder::new()
927 .payload_type(96)
928 .extension(0x9876, [].as_ref())
929 .write_into(&mut data),
930 Err(RtpWriteError::OutputTooSmall(16))
931 );
932 }
933
934 #[test]
935 fn write_rtp_output_too_short_padding() {
936 let mut data = [0; 12];
937 assert_eq!(
938 RtpPacketBuilder::new()
939 .payload_type(96)
940 .padding(1)
941 .write_into(&mut data),
942 Err(RtpWriteError::OutputTooSmall(13))
943 );
944 }
945
946 #[test]
947 fn write_rtp_output_too_short_payload() {
948 let mut data = [0; 12];
949 assert_eq!(
950 RtpPacketBuilder::new()
951 .payload_type(96)
952 .payload([1].as_ref())
953 .write_into(&mut data),
954 Err(RtpWriteError::OutputTooSmall(13))
955 );
956 }
957
958 #[derive(Debug)]
959 struct TestPayload(Vec<u8>);
960
961 impl PayloadLength for TestPayload {
962 fn len(&self) -> usize {
963 self.0.len()
964 }
965 }
966
967 #[derive(Default, Debug)]
968 struct TestRtpWriterCustomPayload {
969 output: Option<Vec<u8>>,
970 padding: Option<u8>,
971 max_size: usize,
972 }
973
974 impl RtpPacketWriter for TestRtpWriterCustomPayload {
975 type Output = Vec<u8>;
976 type Payload = TestPayload;
977 type Extension = TestPayload;
978
979 fn reserve(&mut self, size: usize) {
980 if let Some(output) = self.output.as_mut() {
981 if output.len() < size {
982 output.reserve(size - output.len());
983 }
984 } else {
985 self.output = Some(Vec::with_capacity(size));
986 }
987 }
988
989 fn push(&mut self, data: &[u8]) {
990 let p = self
991 .output
992 .get_or_insert_with(|| Vec::with_capacity(data.len()));
993 println!(
994 "push {} bytes at offset {}, max_size {}",
995 data.len(),
996 p.len(),
997 self.max_size
998 );
999 assert!(p.len() + data.len() <= self.max_size);
1000 p.extend_from_slice(data)
1001 }
1002
1003 fn push_payload(&mut self, payload: &Self::Payload) {
1004 self.push(&payload.0)
1005 }
1006
1007 fn push_extension(&mut self, extension_data: &Self::Extension) {
1008 self.push(&extension_data.0)
1009 }
1010
1011 fn padding(&mut self, size: u8) {
1012 self.padding = Some(size);
1013 }
1014
1015 fn finish(&mut self) -> Self::Output {
1016 self.output
1017 .take()
1018 .map(|mut output| {
1019 if let Some(padding) = self.padding.take() {
1020 output.extend(std::iter::repeat(0).take(padding as usize - 1));
1021 output.push(padding);
1022 }
1023 output
1024 })
1025 .unwrap_or_default()
1026 }
1027 }
1028
1029 #[test]
1030 fn write_rtp_custom_payload() {
1031 let extension_data = TestPayload(vec![1, 2, 3, 4, 5, 6, 7, 8]);
1032 let payload_data = TestPayload(vec![11, 12, 13, 14, 15, 16, 17, 18]);
1033 let builder = RtpPacketBuilder::new()
1034 .payload_type(96)
1035 .marker_bit(true)
1036 .sequence_number(0x0102)
1037 .timestamp(0x03040506)
1038 .ssrc(0x0708090a)
1039 .add_csrc(0x0b0c0d0e)
1040 .extension(0x9876, TestPayload(extension_data.0.clone()))
1041 .payload(TestPayload(payload_data.0.clone()))
1042 .padding(1);
1043 let max_size = builder.calculate_size().unwrap();
1044 let mut writer = TestRtpWriterCustomPayload {
1045 max_size,
1046 ..Default::default()
1047 };
1048 let buf = builder.write(&mut writer).unwrap();
1049 drop(builder);
1050 let data = buf.as_ref();
1051 println!("{data:?}");
1052 let rtp = RtpPacket::parse(data).unwrap();
1053 assert_eq!(rtp.version(), 2);
1054 assert_eq!(rtp.padding(), Some(1));
1055 assert_eq!(rtp.n_csrcs(), 1);
1056 assert!(rtp.marker_bit());
1057 assert_eq!(rtp.payload_type(), 96);
1058 assert_eq!(rtp.sequence_number(), 0x0102);
1059 assert_eq!(rtp.timestamp(), 0x03040506);
1060 assert_eq!(rtp.ssrc(), 0x0708090a);
1061 let mut csrc = rtp.csrc();
1062 assert_eq!(csrc.next(), Some(0x0b0c0d0e));
1063 assert_eq!(csrc.next(), None);
1064 let (ext_id, ext_data) = rtp.extension().unwrap();
1065 assert_eq!(ext_id, 0x9876);
1066 assert_eq!(ext_data, extension_data.0);
1067 assert_eq!(rtp.payload(), payload_data.0);
1068 }
1069
1070 #[test]
1071 fn write_rtp_vec_with_clear() {
1072 let mut vec = vec![];
1073 let payload_data = [1, 2, 3, 4, 5, 6, 7, 8];
1074 let builder = RtpPacketBuilder::new()
1075 .payload_type(96)
1076 .payload(payload_data.as_ref());
1077 let mut writer = RtpPacketWriterMutVec::new(&mut vec);
1078 builder.write(&mut writer).unwrap();
1079 assert_eq!(writer.len(), 20);
1080 let data = writer.as_ref();
1081 println!("{data:?}");
1082 let rtp = RtpPacket::parse(data).unwrap();
1083 assert_eq!(rtp.version(), 2);
1084 assert_eq!(rtp.payload_type(), 96);
1085 assert_eq!(rtp.payload(), payload_data);
1086 writer.clear();
1087 let payload2 = [9, 10, 11];
1088 let builder = builder.clear_payloads().payload(payload2.as_ref());
1089 builder.write(&mut writer).unwrap();
1090 assert_eq!(writer.len(), 15);
1091 let data = writer.as_ref();
1092 println!("{data:?}");
1093 let rtp = RtpPacket::parse(data).unwrap();
1094 assert_eq!(rtp.version(), 2);
1095 assert_eq!(rtp.payload_type(), 96);
1096 assert_eq!(rtp.payload(), payload2);
1097 }
1098}