use bytes::{Bytes, BytesMut};
use std::any::Any;
use super::traits::PayloadFormat;
pub struct G722PayloadFormat {
clock_rate: u32,
sampling_rate: u32,
channels: u8,
preferred_duration: u32,
}
impl G722PayloadFormat {
pub fn new(clock_rate: u32) -> Self {
Self {
clock_rate,
sampling_rate: 16000, channels: 1,
preferred_duration: 20, }
}
pub fn sampling_rate(&self) -> u32 {
self.sampling_rate
}
pub fn actual_samples_from_duration(&self, duration_ms: u32) -> u32 {
(self.sampling_rate * duration_ms) / 1000
}
}
impl PayloadFormat for G722PayloadFormat {
fn payload_type(&self) -> u8 {
9 }
fn clock_rate(&self) -> u32 {
self.clock_rate
}
fn channels(&self) -> u8 {
self.channels
}
fn preferred_packet_duration(&self) -> u32 {
self.preferred_duration
}
fn packet_size_from_duration(&self, duration_ms: u32) -> usize {
let samples_16k = self.actual_samples_from_duration(duration_ms);
((samples_16k * 4) / 8) as usize * self.channels as usize
}
fn duration_from_packet_size(&self, packet_size: usize) -> u32 {
let samples_16k = (packet_size * 2) as u32 / self.channels as u32;
(samples_16k * 1000) / self.sampling_rate
}
fn pack(&self, media_data: &[u8], _timestamp: u32) -> Bytes {
Bytes::copy_from_slice(media_data)
}
fn unpack(&self, payload: &[u8], _timestamp: u32) -> Bytes {
Bytes::copy_from_slice(payload)
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_g722_payload_format() {
let format = G722PayloadFormat::new(8000);
assert_eq!(format.payload_type(), 9);
assert_eq!(format.clock_rate(), 8000);
assert_eq!(format.sampling_rate(), 16000);
assert_eq!(format.channels(), 1);
assert_eq!(format.preferred_packet_duration(), 20);
assert_eq!(format.samples_from_duration(20), 160);
assert_eq!(format.actual_samples_from_duration(20), 320);
assert_eq!(format.packet_size_from_duration(20), 160);
assert_eq!(format.duration_from_packet_size(160), 20);
}
}