msf_rtp/rtcp/
sdes.rs

1use bytes::{BufMut, BytesMut};
2
3use super::{RtcpPacket, RtcpPacketType};
4
5/// Source description.
6#[derive(Clone)]
7pub struct SourceDescription {
8    ssrc: u32,
9    cname: String,
10}
11
12impl SourceDescription {
13    /// Create a new source description.
14    pub fn new<T>(ssrc: u32, cname: T) -> Self
15    where
16        T: Into<String>,
17    {
18        let cname = cname.into();
19
20        assert!(cname.len() < 256);
21
22        Self { ssrc, cname }
23    }
24
25    /// Encode this source description.
26    fn encode(&self, buf: &mut BytesMut) {
27        let old_buffer_length = buf.len();
28
29        buf.put_u32(self.ssrc);
30
31        let data = self.cname.as_bytes();
32
33        buf.put_u8(1);
34        buf.put_u8(data.len() as u8);
35        buf.extend_from_slice(data);
36        buf.put_u8(0);
37
38        while ((buf.len() - old_buffer_length) & 0x03) != 0 {
39            buf.put_u8(0);
40        }
41    }
42
43    /// Get the source description size in bytes.
44    fn raw_size(&self) -> usize {
45        let len = std::mem::size_of::<u32>() + self.cname.len() + 3;
46
47        (len + 3) & !3
48    }
49}
50
51/// Source description packet.
52#[derive(Clone)]
53pub struct SourceDescriptionPacket {
54    chunks: Vec<SourceDescription>,
55}
56
57impl SourceDescriptionPacket {
58    /// Create a new source description packet.
59    #[inline]
60    pub const fn new() -> Self {
61        Self { chunks: Vec::new() }
62    }
63
64    /// Set the source descriptions.
65    ///
66    /// # Panics
67    /// The method will panic if the number of source descriptions is greater
68    /// than 31.
69    pub fn with_source_descriptions<T>(mut self, descriptions: T) -> Self
70    where
71        T: Into<Vec<SourceDescription>>,
72    {
73        let chunks = descriptions.into();
74
75        assert!(chunks.len() < 32);
76
77        self.chunks = chunks;
78        self
79    }
80
81    /// Encode the source description packet.
82    pub fn encode(&self) -> RtcpPacket {
83        let mut payload = BytesMut::with_capacity(self.raw_size());
84
85        for chunk in &self.chunks {
86            chunk.encode(&mut payload);
87        }
88
89        RtcpPacket::new(RtcpPacketType::SDES)
90            .with_item_count(self.chunks.len() as u8)
91            .with_payload(payload.freeze(), 0)
92    }
93
94    /// Get size of the encoded source description packet.
95    pub fn raw_size(&self) -> usize {
96        self.chunks.iter().map(|chunk| chunk.raw_size()).sum()
97    }
98}
99
100impl Default for SourceDescriptionPacket {
101    #[inline]
102    fn default() -> Self {
103        Self::new()
104    }
105}