active_call/media/track/
track_codec.rs

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