use async_trait::async_trait;
use std::sync::Arc;
use std::time::Duration;
use crate::api::common::error::BufferError;
use crate::api::common::frame::MediaFrame;
mod media_buffer_impl;
pub use media_buffer_impl::DefaultMediaBuffer;
#[derive(Debug, Clone)]
pub struct MediaBufferConfig {
pub min_delay_ms: u32,
pub max_delay_ms: u32,
pub adaptive: bool,
pub target_occupancy: u8,
pub max_packet_count: usize,
pub transmit_max_latency_ms: u32,
pub prioritize_keyframes: bool,
}
impl Default for MediaBufferConfig {
fn default() -> Self {
Self {
min_delay_ms: 20,
max_delay_ms: 120,
adaptive: true,
target_occupancy: 50,
max_packet_count: 1000,
transmit_max_latency_ms: 100,
prioritize_keyframes: true,
}
}
}
#[derive(Debug, Clone)]
pub struct BufferStats {
pub current_delay_ms: u32,
pub packet_count: usize,
pub max_delay_seen_ms: u32,
pub min_delay_seen_ms: u32,
pub late_packet_count: u64,
pub overflow_discard_count: u64,
pub average_occupancy: f32,
pub underrun_count: u64,
}
#[async_trait]
pub trait MediaBuffer: Send + Sync {
async fn put_frame(&self, frame: MediaFrame) -> Result<(), BufferError>;
async fn get_frame(&self, timeout: Duration) -> Result<MediaFrame, BufferError>;
async fn get_stats(&self) -> BufferStats;
async fn reset(&self) -> Result<(), BufferError>;
async fn flush(&self) -> Result<Vec<MediaFrame>, BufferError>;
async fn update_config(&self, config: MediaBufferConfig) -> Result<(), BufferError>;
}
pub struct MediaBufferConfigBuilder {
config: MediaBufferConfig,
}
impl MediaBufferConfigBuilder {
pub fn new() -> Self {
Self {
config: MediaBufferConfig::default(),
}
}
pub fn preset(mut self, preset: crate::api::common::config::NetworkPreset) -> Self {
use crate::api::common::config::NetworkPreset;
match preset {
NetworkPreset::LowLatency => {
self.config.min_delay_ms = 10;
self.config.max_delay_ms = 50;
self.config.adaptive = false;
self.config.target_occupancy = 30;
}
NetworkPreset::Balanced => {
}
NetworkPreset::Resilient => {
self.config.min_delay_ms = 50;
self.config.max_delay_ms = 200;
self.config.adaptive = true;
self.config.target_occupancy = 70;
}
NetworkPreset::HighProtection => {
self.config.min_delay_ms = 100;
self.config.max_delay_ms = 500;
self.config.adaptive = true;
self.config.target_occupancy = 80;
}
}
self
}
pub fn audio(mut self) -> Self {
self.config.min_delay_ms = 20;
self.config.max_delay_ms = 120;
self.config.target_occupancy = 50;
self
}
pub fn video(mut self) -> Self {
self.config.min_delay_ms = 50;
self.config.max_delay_ms = 300;
self.config.target_occupancy = 60;
self.config.max_packet_count = 5000;
self.config.prioritize_keyframes = true;
self
}
pub fn min_delay_ms(mut self, delay: u32) -> Self {
self.config.min_delay_ms = delay;
self
}
pub fn max_delay_ms(mut self, delay: u32) -> Self {
self.config.max_delay_ms = delay;
self
}
pub fn adaptive(mut self, adaptive: bool) -> Self {
self.config.adaptive = adaptive;
self
}
pub fn target_occupancy(mut self, occupancy: u8) -> Self {
self.config.target_occupancy = occupancy.min(100);
self
}
pub fn max_packet_count(mut self, count: usize) -> Self {
self.config.max_packet_count = count;
self
}
pub fn transmit_max_latency_ms(mut self, latency: u32) -> Self {
self.config.transmit_max_latency_ms = latency;
self
}
pub fn prioritize_keyframes(mut self, prioritize: bool) -> Self {
self.config.prioritize_keyframes = prioritize;
self
}
pub fn build(self) -> Result<MediaBufferConfig, BufferError> {
if self.config.min_delay_ms > self.config.max_delay_ms {
return Err(BufferError::ConfigurationError(
"Minimum delay must be less than or equal to maximum delay".to_string(),
));
}
if self.config.max_packet_count == 0 {
return Err(BufferError::ConfigurationError(
"Maximum packet count must be greater than zero".to_string(),
));
}
Ok(self.config)
}
}
pub struct MediaBufferFactory;
impl MediaBufferFactory {
pub fn create_buffer(config: MediaBufferConfig) -> Result<Arc<dyn MediaBuffer>, BufferError> {
let buffer = media_buffer_impl::DefaultMediaBuffer::new(config)?;
Ok(buffer as Arc<dyn MediaBuffer>)
}
}