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
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() // Since each codec has its own state, create a fresh instance
48    }
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, // Opus sample rate
110            _ => 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, // Opus sample rate
138                    _ => 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}