voice_engine/media/track/
track_codec.rs1use crate::{
2 media::AudioFrame,
3 media::PcmBuf,
4 media::Samples,
5 media::codecs::{
6 Decoder, Encoder, bytes_to_samples,
7 g722::{G722Decoder, G722Encoder},
8 pcma::{PcmaDecoder, PcmaEncoder},
9 pcmu::{PcmuDecoder, PcmuEncoder},
10 resample::LinearResampler,
11 samples_to_bytes,
12 },
13};
14use std::cell::RefCell;
15
16#[cfg(feature = "g729")]
17use crate::media::codecs::g729::{G729Decoder, G729Encoder};
18#[cfg(feature = "opus")]
19use crate::media::codecs::opus::{OpusDecoder, OpusEncoder};
20
21pub struct TrackCodec {
22 pub pcmu_encoder: RefCell<PcmuEncoder>,
23 pub pcmu_decoder: RefCell<PcmuDecoder>,
24 pub pcma_encoder: RefCell<PcmaEncoder>,
25 pub pcma_decoder: RefCell<PcmaDecoder>,
26
27 pub g722_encoder: RefCell<G722Encoder>,
28 pub g722_decoder: RefCell<G722Decoder>,
29
30 #[cfg(feature = "g729")]
31 pub g729_encoder: RefCell<G729Encoder>,
32 #[cfg(feature = "g729")]
33 pub g729_decoder: RefCell<G729Decoder>,
34
35 #[cfg(feature = "opus")]
36 pub opus_encoder: RefCell<Option<OpusEncoder>>,
37 #[cfg(feature = "opus")]
38 pub opus_decoder: RefCell<Option<OpusDecoder>>,
39
40 pub resampler: RefCell<Option<LinearResampler>>,
41}
42unsafe impl Send for TrackCodec {}
43unsafe impl Sync for TrackCodec {}
44
45impl Clone for TrackCodec {
46 fn clone(&self) -> Self {
47 Self::new() }
49}
50
51impl TrackCodec {
52 pub fn new() -> Self {
53 Self {
54 pcmu_encoder: RefCell::new(PcmuEncoder::new()),
55 pcmu_decoder: RefCell::new(PcmuDecoder::new()),
56 pcma_encoder: RefCell::new(PcmaEncoder::new()),
57 pcma_decoder: RefCell::new(PcmaDecoder::new()),
58 g722_encoder: RefCell::new(G722Encoder::new()),
59 g722_decoder: RefCell::new(G722Decoder::new()),
60 #[cfg(feature = "g729")]
61 g729_encoder: RefCell::new(G729Encoder::new()),
62 #[cfg(feature = "g729")]
63 g729_decoder: RefCell::new(G729Decoder::new()),
64 #[cfg(feature = "opus")]
65 opus_encoder: RefCell::new(None),
66 #[cfg(feature = "opus")]
67 opus_decoder: RefCell::new(None),
68 resampler: RefCell::new(None),
69 }
70 }
71
72 pub fn is_audio(payload_type: u8) -> bool {
73 match payload_type {
74 0 | 8 | 9 => true,
75 #[cfg(feature = "g729")]
76 18 => true,
77 #[cfg(feature = "opus")]
78 111 => true,
79 _ => false,
80 }
81 }
82
83 pub fn decode(&self, payload_type: u8, payload: &[u8], target_sample_rate: u32) -> PcmBuf {
84 let payload = match payload_type {
85 0 => self.pcmu_decoder.borrow_mut().decode(payload),
86 8 => self.pcma_decoder.borrow_mut().decode(payload),
87 9 => self.g722_decoder.borrow_mut().decode(payload),
88 #[cfg(feature = "g729")]
89 18 => self.g729_decoder.borrow_mut().decode(payload),
90 #[cfg(feature = "opus")]
91 111 => {
92 let mut opus_decoder = self.opus_decoder.borrow_mut();
93 if opus_decoder.is_none() {
94 *opus_decoder = Some(OpusDecoder::new_default());
95 }
96 if let Some(ref mut decoder) = opus_decoder.as_mut() {
97 decoder.decode(payload)
98 } else {
99 bytes_to_samples(payload)
100 }
101 }
102 _ => bytes_to_samples(payload),
103 };
104 let sample_rate = match payload_type {
105 0 => 8000,
106 8 => 8000,
107 9 => 16000,
108 18 => 8000,
109 111 => 48000, _ => 8000,
111 };
112 if sample_rate != target_sample_rate {
113 if self.resampler.borrow().is_none() {
114 self.resampler.borrow_mut().replace(
115 LinearResampler::new(sample_rate as usize, target_sample_rate as usize)
116 .unwrap(),
117 );
118 }
119 self.resampler
120 .borrow_mut()
121 .as_mut()
122 .unwrap()
123 .resample(&payload)
124 } else {
125 payload
126 }
127 }
128
129 pub fn encode(&self, payload_type: u8, frame: AudioFrame) -> (u8, Vec<u8>) {
130 match frame.samples {
131 Samples::PCM { samples: mut pcm } => {
132 let target_samplerate = match payload_type {
133 0 => 8000,
134 8 => 8000,
135 9 => 16000,
136 18 => 8000,
137 111 => 48000, _ => 8000,
139 };
140
141 if frame.sample_rate != target_samplerate {
142 if self.resampler.borrow().is_none() {
143 self.resampler.borrow_mut().replace(
144 LinearResampler::new(
145 frame.sample_rate as usize,
146 target_samplerate as usize,
147 )
148 .unwrap(),
149 );
150 }
151 pcm = self.resampler.borrow_mut().as_mut().unwrap().resample(&pcm);
152 }
153
154 let payload = match payload_type {
155 0 => self.pcmu_encoder.borrow_mut().encode(&pcm),
156 8 => self.pcma_encoder.borrow_mut().encode(&pcm),
157 9 => self.g722_encoder.borrow_mut().encode(&pcm),
158 #[cfg(feature = "g729")]
159 18 => self.g729_encoder.borrow_mut().encode(&pcm),
160 #[cfg(feature = "opus")]
161 111 => {
162 let mut opus_encoder = self.opus_encoder.borrow_mut();
163 if opus_encoder.is_none() {
164 *opus_encoder = Some(OpusEncoder::new_default());
165 }
166 if let Some(ref mut encoder) = opus_encoder.as_mut() {
167 encoder.encode(&pcm)
168 } else {
169 samples_to_bytes(&pcm)
170 }
171 }
172 _ => samples_to_bytes(&pcm),
173 };
174 (payload_type, payload)
175 }
176 Samples::RTP {
177 payload_type,
178 payload,
179 ..
180 } => (payload_type, payload),
181 _ => (payload_type, vec![]),
182 }
183 }
184}