Skip to main content

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