rtc_rtp/packet/
mod.rs

1#[cfg(test)]
2mod packet_test;
3
4use crate::header::*;
5use shared::{
6    error::{Error, Result},
7    marshal::{Marshal, MarshalSize, Unmarshal},
8};
9
10use bytes::{Buf, BufMut, Bytes};
11use std::fmt;
12
13/// Packet represents an RTP Packet
14/// NOTE: Raw is populated by Marshal/Unmarshal and should not be modified
15#[derive(Debug, Eq, PartialEq, Default, Clone)]
16pub struct Packet {
17    pub header: Header,
18    pub payload: Bytes,
19}
20
21impl fmt::Display for Packet {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        let mut out = "RTP PACKET:\n".to_string();
24
25        out += format!("\tVersion: {}\n", self.header.version).as_str();
26        out += format!("\tMarker: {}\n", self.header.marker).as_str();
27        out += format!("\tPayload Type: {}\n", self.header.payload_type).as_str();
28        out += format!("\tSequence Number: {}\n", self.header.sequence_number).as_str();
29        out += format!("\tTimestamp: {}\n", self.header.timestamp).as_str();
30        out += format!("\tSSRC: {} ({:x})\n", self.header.ssrc, self.header.ssrc).as_str();
31        out += format!("\tPayload Length: {}\n", self.payload.len()).as_str();
32
33        write!(f, "{out}")
34    }
35}
36
37impl Unmarshal for Packet {
38    /// Unmarshal parses the passed byte slice and stores the result in the Header this method is called upon
39    fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
40    where
41        Self: Sized,
42        B: Buf,
43    {
44        let header = Header::unmarshal(raw_packet)?;
45        let payload_len = raw_packet.remaining();
46        let payload = raw_packet.copy_to_bytes(payload_len);
47        if header.padding {
48            if payload_len > 0 {
49                let padding_len = payload[payload_len - 1] as usize;
50                if padding_len <= payload_len {
51                    Ok(Packet {
52                        header,
53                        payload: payload.slice(..payload_len - padding_len),
54                    })
55                } else {
56                    Err(Error::ErrShortPacket)
57                }
58            } else {
59                Err(Error::ErrShortPacket)
60            }
61        } else {
62            Ok(Packet { header, payload })
63        }
64    }
65}
66
67impl MarshalSize for Packet {
68    /// MarshalSize returns the size of the packet once marshaled.
69    fn marshal_size(&self) -> usize {
70        let payload_len = self.payload.len();
71        let padding_len = if self.header.padding {
72            let padding_len = get_padding(payload_len);
73            if padding_len == 0 {
74                4
75            } else {
76                padding_len
77            }
78        } else {
79            0
80        };
81        self.header.marshal_size() + payload_len + padding_len
82    }
83}
84
85impl Marshal for Packet {
86    /// MarshalTo serializes the packet and writes to the buffer.
87    fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
88        if buf.remaining_mut() < self.marshal_size() {
89            return Err(Error::ErrBufferTooSmall);
90        }
91
92        let n = self.header.marshal_to(buf)?;
93        buf = &mut buf[n..];
94        buf.put(&*self.payload);
95        let padding_len = if self.header.padding {
96            let mut padding_len = get_padding(self.payload.len());
97            if padding_len == 0 {
98                padding_len = 4;
99            }
100            for i in 0..padding_len {
101                if i != padding_len - 1 {
102                    buf.put_u8(0);
103                } else {
104                    buf.put_u8(padding_len as u8);
105                }
106            }
107            padding_len
108        } else {
109            0
110        };
111
112        Ok(n + self.payload.len() + padding_len)
113    }
114}
115
116/// getPadding Returns the padding required to make the length a multiple of 4
117fn get_padding(len: usize) -> usize {
118    if len % 4 == 0 {
119        0
120    } else {
121        4 - (len % 4)
122    }
123}