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}