Skip to main content

ezk_g711/
lib.rs

1use std::{iter::from_fn, mem::take};
2
3use bytes::Bytes;
4use ezk::{ConfigRange, Frame, MediaType};
5use ezk_rtp::{DePayloader, Payloadable, Payloader};
6
7pub mod alaw;
8pub mod mulaw;
9
10mod decoder;
11mod encoder;
12
13pub use decoder::G711Decoder;
14pub use encoder::G711Encoder;
15
16pub type PCMUDecoder<S> = decoder::G711Decoder<S, PCMU>;
17pub type PCMADecoder<S> = decoder::G711Decoder<S, PCMA>;
18
19pub type PCMUEncoder<S> = encoder::G711Encoder<S, PCMU>;
20pub type PCMAEncoder<S> = encoder::G711Encoder<S, PCMA>;
21
22macro_rules! pcmx {
23    ($n:ident, $cr:ident, $c:ident, $pt:expr) => {
24        #[derive(Debug)]
25        pub enum $n {}
26
27        impl MediaType for $n {
28            type ConfigRange = $cr;
29            type Config = $c;
30            type FrameData = Bytes;
31        }
32
33        #[derive(Debug, Clone)]
34        pub struct $cr;
35
36        impl ConfigRange for $cr {
37            type Config = $c;
38
39            fn any() -> Self {
40                Self {}
41            }
42
43            fn intersect(&self, _other: &Self) -> Option<Self> {
44                Some(Self {})
45            }
46
47            fn contains(&self, _config: &Self::Config) -> bool {
48                true
49            }
50        }
51
52        #[derive(Default, Debug, Clone)]
53        pub struct $c;
54
55        impl Payloadable for $n {
56            type Payloader = G711Payloader;
57            type DePayloader = G711DePayloader;
58
59            const STATIC_PT: Option<u8> = Some($pt);
60
61            fn make_payloader(_: Self::Config) -> Self::Payloader {
62                G711Payloader {}
63            }
64
65            fn make_depayloader(_: Vec<Self::ConfigRange>) -> (Self::Config, Self::DePayloader) {
66                (Self::Config {}, G711DePayloader {})
67            }
68        }
69    };
70}
71
72pcmx!(PCMU, PCMUConfigRange, PCMUConfig, 0);
73pcmx!(PCMA, PCMAConfigRange, PCMAConfig, 8);
74
75pub trait PCMX: MediaType<Config: Default, FrameData = Bytes> {
76    fn encode(i: &[i16]) -> Vec<u8>;
77    fn decode(i: &[u8]) -> Vec<i16>;
78}
79
80impl PCMX for PCMA {
81    fn encode(i: &[i16]) -> Vec<u8> {
82        i.iter().copied().map(alaw::encode).collect()
83    }
84
85    fn decode(i: &[u8]) -> Vec<i16> {
86        i.iter().copied().map(alaw::decode).collect()
87    }
88}
89
90impl PCMX for PCMU {
91    fn encode(i: &[i16]) -> Vec<u8> {
92        i.iter().copied().map(mulaw::encode).collect()
93    }
94
95    fn decode(i: &[u8]) -> Vec<i16> {
96        i.iter().copied().map(mulaw::decode).collect()
97    }
98}
99
100pub struct G711Payloader;
101
102impl Payloader<PCMU> for G711Payloader {
103    fn payload(&mut self, frame: Frame<PCMU>, max_size: usize) -> impl Iterator<Item = Bytes> + '_ {
104        split(frame.into_data(), max_size)
105    }
106}
107
108impl Payloader<PCMA> for G711Payloader {
109    fn payload(&mut self, frame: Frame<PCMA>, max_size: usize) -> impl Iterator<Item = Bytes> + '_ {
110        split(frame.into_data(), max_size)
111    }
112}
113
114fn split(mut data: Bytes, max_size: usize) -> impl Iterator<Item = Bytes> {
115    from_fn(move || {
116        if let Some((pkg, rem)) = data.split_at_checked(max_size) {
117            let pkg = data.slice_ref(pkg);
118            data = data.slice_ref(rem);
119            Some(pkg)
120        } else if data.is_empty() {
121            None
122        } else {
123            Some(take(&mut data))
124        }
125    })
126}
127
128pub struct G711DePayloader;
129
130impl DePayloader<PCMU> for G711DePayloader {
131    fn depayload(&mut self, payload: &[u8]) -> Bytes {
132        Bytes::copy_from_slice(payload)
133    }
134}
135
136impl DePayloader<PCMA> for G711DePayloader {
137    fn depayload(&mut self, payload: &[u8]) -> Bytes {
138        Bytes::copy_from_slice(payload)
139    }
140}