Skip to main content

rtc_rtp/packetizer/
mod.rs

1#[cfg(test)]
2mod packetizer_test;
3
4use crate::{extension::abs_send_time_extension::*, header::*, packet::*, sequence::*};
5use shared::{
6    error::Result,
7    marshal::{Marshal, MarshalSize},
8    time::SystemInstant,
9};
10
11use bytes::{Bytes, BytesMut};
12use std::fmt;
13use std::time::Instant;
14
15/// Payloader payloads a byte array for use as rtp.Packet payloads
16pub trait Payloader: Send + Sync + fmt::Debug {
17    /// Splits one encoded frame into payloads no larger than `mtu`.
18    ///
19    /// # Errors
20    ///
21    /// Fails if the frame is malformed for this codec, or `mtu` is too small to make progress.
22    fn payload(&mut self, mtu: usize, b: &Bytes) -> Result<Vec<Bytes>>;
23    /// Clones this payloader behind a trait object.
24    fn clone_to(&self) -> Box<dyn Payloader>;
25}
26
27impl Clone for Box<dyn Payloader> {
28    fn clone(&self) -> Box<dyn Payloader> {
29        self.clone_to()
30    }
31}
32
33/// Packetizer packetizes a payload
34pub trait Packetizer: Send + Sync + fmt::Debug {
35    /// Attaches the absolute-send-time header extension under id `value`.
36    fn enable_abs_send_time(&mut self, value: u8);
37    /// Packetizes one frame, advancing the timestamp by `samples`.
38    ///
39    /// Assigns sequence numbers, sets the marker bit on the final packet, and applies any
40    /// enabled header extensions. `now` is the instant the frame is being sent at; it is what
41    /// the absolute-send-time extension is derived from, so the caller supplies it rather than
42    /// the packetizer sampling a clock of its own.
43    ///
44    /// # Errors
45    ///
46    /// Propagates payloader failures.
47    fn packetize(&mut self, now: Instant, payload: &Bytes, samples: u32) -> Result<Vec<Packet>>;
48    /// Advances the timestamp without sending anything, for dropped or silent frames.
49    fn skip_samples(&mut self, skipped_samples: u32);
50    /// Clones this packetizer behind a trait object.
51    fn clone_to(&self) -> Box<dyn Packetizer>;
52}
53
54impl Clone for Box<dyn Packetizer> {
55    fn clone(&self) -> Box<dyn Packetizer> {
56        self.clone_to()
57    }
58}
59
60/// Depacketizer depacketizes a RTP payload, removing any RTP specific data from the payload
61pub trait Depacketizer {
62    /// Reassembles a frame from one RTP payload, buffering fragments as needed.
63    ///
64    /// # Errors
65    ///
66    /// Fails if the payload is malformed for this codec.
67    fn depacketize(&mut self, b: &Bytes) -> Result<Bytes>;
68
69    /// Checks if the packet is at the beginning of a partition.  This
70    /// should return false if the result could not be determined, in
71    /// which case the caller will detect timestamp discontinuities.
72    fn is_partition_head(&self, payload: &Bytes) -> bool;
73
74    /// Checks if the packet is at the end of a partition.  This should
75    /// return false if the result could not be determined.
76    fn is_partition_tail(&self, marker: bool, payload: &Bytes) -> bool;
77}
78
79#[derive(Clone)]
80pub(crate) struct PacketizerImpl {
81    pub(crate) mtu: usize,
82    pub(crate) payload_type: u8,
83    pub(crate) ssrc: u32,
84    pub(crate) payloader: Box<dyn Payloader>,
85    pub(crate) sequencer: Box<dyn Sequencer>,
86    pub(crate) timestamp: u32,
87    pub(crate) clock_rate: u32,
88    pub(crate) abs_send_time_ext_id: u8, //http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
89    pub(crate) time_baseline: SystemInstant,
90}
91
92impl fmt::Debug for PacketizerImpl {
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        f.debug_struct("PacketizerImpl")
95            .field("mtu", &self.mtu)
96            .field("payload_type", &self.payload_type)
97            .field("ssrc", &self.ssrc)
98            .field("timestamp", &self.timestamp)
99            .field("clock_rate", &self.clock_rate)
100            .field("abs_send_time_ext_id", &self.abs_send_time_ext_id)
101            .finish()
102    }
103}
104
105/// Builds a packetizer for one outbound stream.
106///
107/// Ties together the codec's payloader, a sequencer, and the SSRC, payload type, MTU and clock
108/// rate the stream was negotiated with.
109pub fn new_packetizer(
110    now: Instant,
111    mtu: usize,
112    payload_type: u8,
113    ssrc: u32,
114    payloader: Box<dyn Payloader>,
115    sequencer: Box<dyn Sequencer>,
116    clock_rate: u32,
117) -> impl Packetizer {
118    PacketizerImpl {
119        mtu,
120        payload_type,
121        ssrc,
122        payloader,
123        sequencer,
124        timestamp: rand::random::<u32>(),
125        clock_rate,
126        abs_send_time_ext_id: 0,
127        time_baseline: SystemInstant::now(now),
128    }
129}
130
131impl Packetizer for PacketizerImpl {
132    fn enable_abs_send_time(&mut self, id: u8) {
133        self.abs_send_time_ext_id = id
134    }
135
136    fn packetize(&mut self, now: Instant, payload: &Bytes, samples: u32) -> Result<Vec<Packet>> {
137        let payloads = self.payloader.payload(self.mtu - 12, payload)?;
138        let payloads_len = payloads.len();
139        let mut packets = Vec::with_capacity(payloads_len);
140        for (i, payload) in payloads.into_iter().enumerate() {
141            packets.push(Packet {
142                header: Header {
143                    version: 2,
144                    padding: false,
145                    extension: false,
146                    marker: i == payloads_len - 1,
147                    payload_type: self.payload_type,
148                    sequence_number: self.sequencer.next_sequence_number(),
149                    timestamp: self.timestamp, //TODO: Figure out how to do timestamps
150                    ssrc: self.ssrc,
151                    ..Default::default()
152                },
153                payload,
154            });
155        }
156
157        self.timestamp = self.timestamp.wrapping_add(samples);
158
159        if payloads_len != 0 && self.abs_send_time_ext_id != 0 {
160            let send_time = AbsSendTimeExtension::new(self.time_baseline.ntp(now));
161            //apply http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
162            let mut raw = BytesMut::with_capacity(send_time.marshal_size());
163            raw.resize(send_time.marshal_size(), 0);
164            let _ = send_time.marshal_to(&mut raw)?;
165            packets[payloads_len - 1]
166                .header
167                .set_extension(self.abs_send_time_ext_id, raw.freeze())?;
168        }
169
170        Ok(packets)
171    }
172
173    /// skip_samples causes a gap in sample count between Packetize requests so the
174    /// RTP payloads produced have a gap in timestamps
175    fn skip_samples(&mut self, skipped_samples: u32) {
176        self.timestamp = self.timestamp.wrapping_add(skipped_samples);
177    }
178
179    fn clone_to(&self) -> Box<dyn Packetizer> {
180        Box::new(self.clone())
181    }
182}