voice_engine/media/track/
track_codec.rs

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