1use crate::{media::AudioFrame, media::PcmBuf, media::Samples};
2use audio_codec::{
3 CodecType, Decoder, Encoder, Resampler, bytes_to_samples,
4 g722::{G722Decoder, G722Encoder},
5 pcma::{PcmaDecoder, PcmaEncoder},
6 pcmu::{PcmuDecoder, PcmuEncoder},
7 samples_to_bytes,
8};
9use std::collections::HashMap;
10
11use audio_codec::g729::{G729Decoder, G729Encoder};
12#[cfg(feature = "opus")]
13use audio_codec::opus::{OpusDecoder, OpusEncoder};
14
15pub struct TrackCodec {
16 pcmu_encoder: PcmuEncoder,
17 pcmu_decoder: PcmuDecoder,
18 pcma_encoder: PcmaEncoder,
19 pcma_decoder: PcmaDecoder,
20
21 g722_encoder: Option<Box<G722Encoder>>,
22 g722_decoder: Option<Box<G722Decoder>>,
23
24 g729_encoder: Option<Box<G729Encoder>>,
25 g729_decoder: Option<Box<G729Decoder>>,
26
27 #[cfg(feature = "opus")]
28 opus_encoder: Option<OpusEncoder>,
29 #[cfg(feature = "opus")]
30 opus_decoder: Option<OpusDecoder>,
31
32 resampler: Option<Resampler>,
33 resampler_in_rate: u32,
34 resampler_out_rate: u32,
35 pub payload_type_map: HashMap<u8, CodecType>,
36}
37
38impl Clone for TrackCodec {
39 fn clone(&self) -> Self {
40 let mut new = Self::new();
41 new.payload_type_map = self.payload_type_map.clone();
42 new
43 }
44}
45
46impl TrackCodec {
47 pub fn new() -> Self {
48 let mut payload_type_map = HashMap::new();
49 payload_type_map.insert(0, CodecType::PCMU);
50 payload_type_map.insert(8, CodecType::PCMA);
51 payload_type_map.insert(9, CodecType::G722);
52 payload_type_map.insert(18, CodecType::G729);
53 payload_type_map.insert(101, CodecType::TelephoneEvent);
54 payload_type_map.insert(111, CodecType::Opus);
55
56 Self {
57 pcmu_encoder: PcmuEncoder::new(),
58 pcmu_decoder: PcmuDecoder::new(),
59 pcma_encoder: PcmaEncoder::new(),
60 pcma_decoder: PcmaDecoder::new(),
61 g722_encoder: None,
62 g722_decoder: None,
63 g729_encoder: None,
64 g729_decoder: None,
65 #[cfg(feature = "opus")]
66 opus_encoder: None,
67 #[cfg(feature = "opus")]
68 opus_decoder: None,
69 resampler: None,
70 resampler_in_rate: 0,
71 resampler_out_rate: 0,
72 payload_type_map,
73 }
74 }
75
76 pub fn set_payload_type(&mut self, pt: u8, codec: CodecType) {
77 self.payload_type_map.insert(pt, codec);
78 }
79
80 pub fn is_audio(payload_type: u8) -> bool {
81 match payload_type {
82 0 | 8 | 9 | 18 | 111 => true,
83 pt if pt >= 96 && pt <= 127 => true,
84 _ => false,
85 }
86 }
87
88 pub fn decode(
89 &mut self,
90 payload_type: u8,
91 payload: &[u8],
92 target_sample_rate: u32,
93 ) -> (u32, u16, PcmBuf) {
94 let codec = self
95 .payload_type_map
96 .get(&payload_type)
97 .cloned()
98 .unwrap_or_else(|| match payload_type {
99 0 => CodecType::PCMU,
100 8 => CodecType::PCMA,
101 9 => CodecType::G722,
102 18 => CodecType::G729,
103 111 => CodecType::Opus,
104 _ => CodecType::PCMU,
105 });
106
107 let pcm = match codec {
108 CodecType::PCMU => self.pcmu_decoder.decode(payload),
109 CodecType::PCMA => self.pcma_decoder.decode(payload),
110 CodecType::G722 => self
111 .g722_decoder
112 .get_or_insert_with(|| Box::new(G722Decoder::new()))
113 .decode(payload),
114 CodecType::G729 => self
115 .g729_decoder
116 .get_or_insert_with(|| Box::new(G729Decoder::new()))
117 .decode(payload),
118 #[cfg(feature = "opus")]
119 CodecType::Opus => self
120 .opus_decoder
121 .get_or_insert_with(OpusDecoder::new_default)
122 .decode(payload),
123 _ => bytes_to_samples(payload),
124 };
125
126 let (in_rate, channels) = match codec {
127 CodecType::PCMU => (8000, 1),
128 CodecType::PCMA => (8000, 1),
129 CodecType::G722 => (16000, 1),
130 CodecType::G729 => (8000, 1),
131 #[cfg(feature = "opus")]
132 CodecType::Opus => {
133 if pcm.len() >= 1920 {
134 (48000, 2)
135 } else {
136 (48000, 1)
137 }
138 }
139 _ => (8000, 1),
140 };
141
142 (
143 target_sample_rate,
144 channels,
145 self.resample(pcm, in_rate, target_sample_rate),
146 )
147 }
148
149 pub fn resample(&mut self, pcm: PcmBuf, in_rate: u32, out_rate: u32) -> PcmBuf {
150 if in_rate == out_rate {
151 return pcm;
152 }
153
154 if self.resampler.is_none()
155 || self.resampler_in_rate != in_rate
156 || self.resampler_out_rate != out_rate
157 {
158 self.resampler = Some(Resampler::new(in_rate as usize, out_rate as usize));
159 self.resampler_in_rate = in_rate;
160 self.resampler_out_rate = out_rate;
161 }
162 self.resampler.as_mut().unwrap().resample(&pcm)
163 }
164
165 pub fn encode(&mut self, payload_type: u8, frame: AudioFrame) -> (u8, Vec<u8>) {
166 match frame.samples {
167 Samples::PCM { samples: mut pcm } => {
168 let target_samplerate = match payload_type {
169 0 => 8000,
170 8 => 8000,
171 9 => 16000,
172 18 => 8000,
173 111 => 48000, _ => 8000,
175 };
176
177 if frame.sample_rate != target_samplerate {
178 if self.resampler.is_none()
179 || self.resampler_in_rate != frame.sample_rate
180 || self.resampler_out_rate != target_samplerate
181 {
182 self.resampler = Some(Resampler::new(
183 frame.sample_rate as usize,
184 target_samplerate as usize,
185 ));
186 self.resampler_in_rate = frame.sample_rate;
187 self.resampler_out_rate = target_samplerate;
188 }
189 pcm = self.resampler.as_mut().unwrap().resample(&pcm);
190 }
191
192 let payload = match payload_type {
193 0 => self.pcmu_encoder.encode(&pcm),
194 8 => self.pcma_encoder.encode(&pcm),
195 9 => self
196 .g722_encoder
197 .get_or_insert_with(|| Box::new(G722Encoder::new()))
198 .encode(&pcm),
199 18 => self
200 .g729_encoder
201 .get_or_insert_with(|| Box::new(G729Encoder::new()))
202 .encode(&pcm),
203 #[cfg(feature = "opus")]
204 111 => self
205 .opus_encoder
206 .get_or_insert_with(OpusEncoder::new_default)
207 .encode(&pcm),
208 _ => samples_to_bytes(&pcm),
209 };
210 (payload_type, payload)
211 }
212 Samples::RTP {
213 payload_type,
214 payload,
215 ..
216 } => (payload_type, payload),
217 _ => (payload_type, vec![]),
218 }
219 }
220}