pub mod g722;
#[cfg(feature = "g729-codec")]
pub mod g729_codec;
#[cfg(feature = "opus-codec")]
pub mod opus_codec;
pub mod pcma;
pub mod pcmu;
pub trait CodecProcessor: Send {
fn decode(&mut self, payload: &[u8]) -> Vec<i16>;
fn encode(&mut self, samples: &[i16]) -> Vec<u8>;
fn payload_type(&self) -> u8;
fn clock_rate(&self) -> u32;
fn samples_per_frame(&self) -> u32;
}
pub fn new_codec_processor(payload_type: i32, pcm_rate: i32) -> Option<Box<dyn CodecProcessor>> {
match payload_type {
0 => Some(Box::new(pcmu::PcmuProcessor::new())),
8 => Some(Box::new(pcma::PcmaProcessor::new())),
9 => Some(Box::new(g722::G722Processor::new(pcm_rate as u32))),
#[cfg(feature = "g729-codec")]
18 => g729_codec::G729Processor::new().map(|p| Box::new(p) as Box<dyn CodecProcessor>),
#[cfg(feature = "opus-codec")]
111 => opus_codec::OpusProcessor::new().map(|p| Box::new(p) as Box<dyn CodecProcessor>),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn codec_processor_pcmu_interface() {
let cp = new_codec_processor(0, 8000).unwrap();
assert_eq!(cp.payload_type(), 0);
assert_eq!(cp.clock_rate(), 8000);
assert_eq!(cp.samples_per_frame(), 160);
}
#[test]
fn codec_processor_pcma_interface() {
let cp = new_codec_processor(8, 8000).unwrap();
assert_eq!(cp.payload_type(), 8);
assert_eq!(cp.clock_rate(), 8000);
assert_eq!(cp.samples_per_frame(), 160);
}
#[test]
fn codec_processor_g722_interface() {
let cp = new_codec_processor(9, 8000).unwrap();
assert_eq!(cp.payload_type(), 9);
assert_eq!(cp.clock_rate(), 8000);
assert_eq!(cp.samples_per_frame(), 160);
}
#[test]
fn codec_processor_unknown_returns_none() {
assert!(new_codec_processor(99, 8000).is_none());
}
#[cfg(not(feature = "g729-codec"))]
#[test]
fn codec_processor_g729_without_feature_returns_none() {
assert!(new_codec_processor(18, 8000).is_none());
}
#[cfg(feature = "g729-codec")]
#[test]
fn codec_processor_g729_with_feature_returns_some() {
let cp = new_codec_processor(18, 8000).unwrap();
assert_eq!(cp.payload_type(), 18);
assert_eq!(cp.clock_rate(), 8000);
assert_eq!(cp.samples_per_frame(), 160);
}
#[cfg(not(feature = "opus-codec"))]
#[test]
fn codec_processor_opus_without_feature_returns_none() {
assert!(new_codec_processor(111, 8000).is_none());
}
#[cfg(feature = "opus-codec")]
#[test]
fn codec_processor_opus_with_feature_returns_some() {
let cp = new_codec_processor(111, 8000).unwrap();
assert_eq!(cp.payload_type(), 111);
assert_eq!(cp.clock_rate(), 48000);
assert_eq!(cp.samples_per_frame(), 960);
}
}