atm0s_custom_str0m/packet/
mod.rs

1#![allow(clippy::type_complexity)]
2#![allow(unused)]
3
4use std::fmt;
5use std::panic::UnwindSafe;
6use thiserror::Error;
7
8use crate::format::Codec;
9use crate::sdp::MediaType;
10
11mod g7xx;
12use g7xx::{G711Packetizer, G722Packetizer};
13
14mod h264;
15pub use h264::H264CodecExtra;
16use h264::{H264Depacketizer, H264Packetizer};
17
18mod h264_profile;
19pub(crate) use h264_profile::H264ProfileLevel;
20
21mod h265;
22use h265::H265Depacketizer;
23
24mod opus;
25use opus::{OpusDepacketizer, OpusPacketizer};
26
27mod vp8;
28pub use vp8::Vp8CodecExtra;
29use vp8::{Vp8Depacketizer, Vp8Packetizer};
30
31mod vp9;
32pub use vp9::Vp9CodecExtra;
33use vp9::{Vp9Depacketizer, Vp9Packetizer};
34
35mod null;
36use null::{NullDepacketizer, NullPacketizer};
37
38mod buffer_rx;
39pub(crate) use buffer_rx::{Depacketized, DepacketizingBuffer, RtpMeta};
40mod contiguity;
41mod contiguity_vp8;
42mod contiguity_vp9;
43
44mod payload;
45pub(crate) use payload::Payloader;
46
47mod bwe;
48pub(crate) use bwe::SendSideBandwithEstimator;
49
50mod pacer;
51pub(crate) use pacer::{LeakyBucketPacer, NullPacer, Pacer, PacerImpl};
52pub(crate) use pacer::{QueuePriority, QueueSnapshot, QueueState};
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
55/// Types of media.
56pub enum MediaKind {
57    /// Audio media.
58    Audio,
59    /// Video media.
60    Video,
61}
62
63impl MediaKind {
64    /// Tests if this is `MediaKind::Audio`
65    pub fn is_audio(&self) -> bool {
66        *self == MediaKind::Audio
67    }
68
69    /// Tests if this is `MediaKind::Video`
70    pub fn is_video(&self) -> bool {
71        *self == MediaKind::Video
72    }
73}
74
75/// Packetizes some bytes for use as RTP packet.
76pub(crate) trait Packetizer: fmt::Debug {
77    /// Chunk the data up into RTP packets.
78    fn packetize(&mut self, mtu: usize, b: &[u8]) -> Result<Vec<Vec<u8>>, PacketError>;
79
80    fn is_marker(&mut self, data: &[u8], previous: Option<&[u8]>, last: bool) -> bool;
81}
82
83/// Codec specific information
84///
85/// Contains additional codec specific information which are deemed useful for
86/// managing and repackaging the sample
87#[derive(Debug, Clone, Copy, PartialEq, Eq)]
88pub enum CodecExtra {
89    /// No extra information available
90    None,
91    /// Codec extra parameters for VP8.
92    Vp8(Vp8CodecExtra),
93    /// Codec extra parameters for VP9.
94    Vp9(Vp9CodecExtra),
95    /// Codec extra parameters for H264.
96    H264(H264CodecExtra),
97}
98
99/// Depacketizes an RTP payload.
100///
101/// Removes any RTP specific data from the payload.
102pub(crate) trait Depacketizer: fmt::Debug {
103    /// Unpack the RTP packet into a provided `Vec<u8>`.
104    fn depacketize(
105        &mut self,
106        packet: &[u8],
107        out: &mut Vec<u8>,
108        codec_extra: &mut CodecExtra,
109    ) -> Result<(), PacketError>;
110
111    /// Checks if the packet is at the beginning of a partition.
112    ///
113    /// Returns false if the result could not be determined.
114    fn is_partition_head(&self, packet: &[u8]) -> bool;
115
116    /// Checks if the packet is at the end of a partition.
117    ///
118    /// Returns false if the result could not be determined.
119    fn is_partition_tail(&self, marker: bool, packet: &[u8]) -> bool;
120}
121
122/// Errors arising in packet- and depacketization.
123#[derive(Debug, Error, PartialEq, Eq)]
124#[allow(missing_docs)]
125pub enum PacketError {
126    #[error("Packet is too short")]
127    ErrShortPacket,
128    #[error("Too many spatial layers")]
129    ErrTooManySpatialLayers,
130    #[error("Too many P-Diff")]
131    ErrTooManyPDiff,
132    #[error("H265 corrupted packet")]
133    ErrH265CorruptedPacket,
134    #[error("H265 invalid packet type")]
135    ErrInvalidH265PacketType,
136    #[error("H264 StapA size larger than buffer: {0} > {1}")]
137    StapASizeLargerThanBuffer(usize, usize),
138    #[error("H264 NALU type is not handled: {0}")]
139    NaluTypeIsNotHandled(u8),
140    #[error("VP9 corrupted packet")]
141    ErrVP9CorruptedPacket,
142}
143
144/// Helper to replace Bytes. Provides get_u8 and get_u16 over some buffer of bytes.
145pub(crate) trait BitRead {
146    fn remaining(&self) -> usize;
147    fn get_u8(&mut self) -> Option<u8>;
148    fn get_u16(&mut self) -> Option<u16>;
149}
150
151impl BitRead for (&[u8], usize) {
152    #[inline(always)]
153    fn remaining(&self) -> usize {
154        (self.0.len() * 8).saturating_sub(self.1)
155    }
156
157    #[inline(always)]
158    fn get_u8(&mut self) -> Option<u8> {
159        if self.remaining() < 8 {
160            return None;
161        }
162
163        let offs = self.1 / 8;
164        let shift = (self.1 % 8) as u32;
165        self.1 += 8;
166
167        let mut n = self.0[offs];
168
169        if shift > 0 {
170            n <<= shift;
171            n |= self.0[offs + 1] >> (8 - shift)
172        }
173
174        Some(n)
175    }
176
177    fn get_u16(&mut self) -> Option<u16> {
178        if self.remaining() < 16 {
179            return None;
180        }
181        Some(u16::from_be_bytes([self.get_u8()?, self.get_u8()?]))
182    }
183}
184
185#[derive(Debug)]
186pub(crate) enum CodecPacketizer {
187    G711(G711Packetizer),
188    G722(G722Packetizer),
189    H264(H264Packetizer),
190    // H265() TODO
191    Opus(OpusPacketizer),
192    Vp8(Vp8Packetizer),
193    Vp9(Vp9Packetizer),
194    Null(NullPacketizer),
195    Boxed(Box<dyn Packetizer + Send + Sync + UnwindSafe>),
196}
197
198#[derive(Debug)]
199pub(crate) enum CodecDepacketizer {
200    H264(H264Depacketizer),
201    H265(H265Depacketizer),
202    Opus(OpusDepacketizer),
203    Vp8(Vp8Depacketizer),
204    Vp9(Vp9Depacketizer),
205    Null(NullDepacketizer),
206    Boxed(Box<dyn Depacketizer + Send + Sync + UnwindSafe>),
207}
208
209impl From<Codec> for CodecPacketizer {
210    fn from(c: Codec) -> Self {
211        match c {
212            Codec::Opus => CodecPacketizer::Opus(OpusPacketizer),
213            Codec::H264 => CodecPacketizer::H264(H264Packetizer::default()),
214            Codec::H265 => unimplemented!("Missing packetizer for H265"),
215            Codec::Vp8 => CodecPacketizer::Vp8(Vp8Packetizer::default()),
216            Codec::Vp9 => CodecPacketizer::Vp9(Vp9Packetizer::default()),
217            Codec::Av1 => unimplemented!("Missing packetizer for AV1"),
218            Codec::Null => CodecPacketizer::Null(NullPacketizer),
219            Codec::Rtx => panic!("Cant instantiate packetizer for RTX codec"),
220            Codec::Unknown => panic!("Cant instantiate packetizer for unknown codec"),
221            _ => panic!("Cant instantiate packetizer for unhandled codec"),
222        }
223    }
224}
225
226impl From<Codec> for CodecDepacketizer {
227    fn from(c: Codec) -> Self {
228        match c {
229            Codec::Opus => CodecDepacketizer::Opus(OpusDepacketizer),
230            Codec::H264 => CodecDepacketizer::H264(H264Depacketizer::default()),
231            Codec::H265 => CodecDepacketizer::H265(H265Depacketizer::default()),
232            Codec::Vp8 => CodecDepacketizer::Vp8(Vp8Depacketizer::default()),
233            Codec::Vp9 => CodecDepacketizer::Vp9(Vp9Depacketizer::default()),
234            Codec::Av1 => unimplemented!("Missing depacketizer for AV1"),
235            Codec::Null => CodecDepacketizer::Null(NullDepacketizer),
236            Codec::Rtx => panic!("Cant instantiate depacketizer for RTX codec"),
237            Codec::Unknown => panic!("Cant instantiate depacketizer for unknown codec"),
238            _ => panic!("Cant instantiate packetizer for unhandled codec"),
239        }
240    }
241}
242
243impl Packetizer for CodecPacketizer {
244    fn packetize(&mut self, mtu: usize, b: &[u8]) -> Result<Vec<Vec<u8>>, PacketError> {
245        use CodecPacketizer::*;
246        match self {
247            G711(v) => v.packetize(mtu, b),
248            G722(v) => v.packetize(mtu, b),
249            H264(v) => v.packetize(mtu, b),
250            Opus(v) => v.packetize(mtu, b),
251            Vp8(v) => v.packetize(mtu, b),
252            Vp9(v) => v.packetize(mtu, b),
253            Null(v) => v.packetize(mtu, b),
254            Boxed(v) => v.packetize(mtu, b),
255        }
256    }
257
258    fn is_marker(&mut self, data: &[u8], previous: Option<&[u8]>, last: bool) -> bool {
259        match self {
260            CodecPacketizer::G711(v) => v.is_marker(data, previous, last),
261            CodecPacketizer::G722(v) => v.is_marker(data, previous, last),
262            CodecPacketizer::Opus(v) => v.is_marker(data, previous, last),
263            CodecPacketizer::H264(v) => v.is_marker(data, previous, last),
264            CodecPacketizer::Vp8(v) => v.is_marker(data, previous, last),
265            CodecPacketizer::Vp9(v) => v.is_marker(data, previous, last),
266            CodecPacketizer::Null(v) => v.is_marker(data, previous, last),
267            CodecPacketizer::Boxed(v) => v.is_marker(data, previous, last),
268        }
269    }
270}
271
272impl Depacketizer for CodecDepacketizer {
273    fn depacketize(
274        &mut self,
275        packet: &[u8],
276        out: &mut Vec<u8>,
277        extra: &mut CodecExtra,
278    ) -> Result<(), PacketError> {
279        use CodecDepacketizer::*;
280        match self {
281            H264(v) => v.depacketize(packet, out, extra),
282            H265(v) => v.depacketize(packet, out, extra),
283            Opus(v) => v.depacketize(packet, out, extra),
284            Vp8(v) => v.depacketize(packet, out, extra),
285            Vp9(v) => v.depacketize(packet, out, extra),
286            Null(v) => v.depacketize(packet, out, extra),
287            Boxed(v) => v.depacketize(packet, out, extra),
288        }
289    }
290
291    fn is_partition_head(&self, packet: &[u8]) -> bool {
292        use CodecDepacketizer::*;
293        match self {
294            H264(v) => v.is_partition_head(packet),
295            H265(v) => v.is_partition_head(packet),
296            Opus(v) => v.is_partition_head(packet),
297            Vp8(v) => v.is_partition_head(packet),
298            Vp9(v) => v.is_partition_head(packet),
299            Null(v) => v.is_partition_head(packet),
300            Boxed(v) => v.is_partition_head(packet),
301        }
302    }
303
304    fn is_partition_tail(&self, marker: bool, packet: &[u8]) -> bool {
305        use CodecDepacketizer::*;
306        match self {
307            H264(v) => v.is_partition_tail(marker, packet),
308            H265(v) => v.is_partition_tail(marker, packet),
309            Opus(v) => v.is_partition_tail(marker, packet),
310            Vp8(v) => v.is_partition_tail(marker, packet),
311            Vp9(v) => v.is_partition_tail(marker, packet),
312            Null(v) => v.is_partition_tail(marker, packet),
313            Boxed(v) => v.is_partition_tail(marker, packet),
314        }
315    }
316}
317
318impl From<MediaType> for MediaKind {
319    fn from(v: MediaType) -> Self {
320        match v {
321            MediaType::Audio => MediaKind::Audio,
322            MediaType::Video => MediaKind::Video,
323            _ => panic!("Not MediaType::Audio or Video"),
324        }
325    }
326}
327
328impl fmt::Display for MediaKind {
329    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
330        match self {
331            MediaKind::Audio => write!(f, "audio"),
332            MediaKind::Video => write!(f, "video"),
333        }
334    }
335}