use crate::api::common::extension::ExtensionFormat;
use crate::api::server::security::ServerSecurityConfig;
use crate::buffer::{BufferLimits, TransmitBufferConfig};
use crate::session::RtpSessionBufferConfig;
use crate::transport::RtpTransportBufferConfig;
use std::net::SocketAddr;
#[derive(Debug, Clone)]
pub struct ServerConfig {
pub local_address: SocketAddr,
pub default_payload_type: u8,
pub clock_rate: u32,
pub security_config: ServerSecurityConfig,
pub jitter_buffer_size: u32,
pub jitter_max_packet_age_ms: u32,
pub enable_jitter_buffer: bool,
pub max_clients: usize,
pub rtcp_mux: bool,
pub media_sync_enabled: Option<bool>,
pub ssrc_demultiplexing_enabled: Option<bool>,
pub csrc_management_enabled: bool,
pub header_extensions_enabled: bool,
pub header_extension_format: ExtensionFormat,
pub transmit_buffer_config: TransmitBufferConfig,
pub buffer_limits: BufferLimits,
pub high_performance_buffers_enabled: bool,
pub rtp_session_buffer_config: RtpSessionBufferConfig,
pub rtp_transport_buffer_config: RtpTransportBufferConfig,
pub frame_channel_capacity: usize,
}
#[derive(Debug, Clone)]
pub struct ServerConfigBuilder {
config: ServerConfig,
}
impl ServerConfigBuilder {
pub fn new() -> Self {
Self {
config: ServerConfig {
local_address: "0.0.0.0:0".parse().unwrap(),
default_payload_type: 0,
clock_rate: 8000,
security_config: ServerSecurityConfig::default(),
jitter_buffer_size: 100,
jitter_max_packet_age_ms: 500,
enable_jitter_buffer: true,
max_clients: 100,
rtcp_mux: false, media_sync_enabled: None, ssrc_demultiplexing_enabled: None, csrc_management_enabled: false, header_extensions_enabled: false, header_extension_format: ExtensionFormat::OneByte, transmit_buffer_config: TransmitBufferConfig::default(),
buffer_limits: BufferLimits {
max_packets_per_stream: 500,
max_packet_size: 1500,
max_memory: 100 * 1024 * 1024, },
high_performance_buffers_enabled: false,
rtp_session_buffer_config: RtpSessionBufferConfig::default(),
rtp_transport_buffer_config: RtpTransportBufferConfig::default(),
frame_channel_capacity: 16,
},
}
}
pub fn webrtc() -> Self {
let mut builder = Self::new();
builder.config.security_config.security_mode =
crate::api::common::config::SecurityMode::DtlsSrtp;
builder.config.rtcp_mux = true; builder.config.header_extensions_enabled = true; builder
}
pub fn sip() -> Self {
let mut builder = Self::new();
builder.config.security_config.security_mode =
crate::api::common::config::SecurityMode::Srtp;
builder.config.rtcp_mux = false; builder
}
pub fn local_address(mut self, addr: SocketAddr) -> Self {
self.config.local_address = addr;
self
}
pub fn default_payload_type(mut self, pt: u8) -> Self {
self.config.default_payload_type = pt;
self
}
pub fn clock_rate(mut self, rate: u32) -> Self {
self.config.clock_rate = rate;
self
}
pub fn security_config(mut self, config: ServerSecurityConfig) -> Self {
self.config.security_config = config;
self
}
pub fn jitter_buffer_size(mut self, size: u32) -> Self {
self.config.jitter_buffer_size = size;
self
}
pub fn jitter_max_packet_age_ms(mut self, age: u32) -> Self {
self.config.jitter_max_packet_age_ms = age;
self
}
pub fn enable_jitter_buffer(mut self, enable: bool) -> Self {
self.config.enable_jitter_buffer = enable;
self
}
pub fn max_clients(mut self, max: usize) -> Self {
self.config.max_clients = max;
self
}
pub fn rtcp_mux(mut self, enable: bool) -> Self {
self.config.rtcp_mux = enable;
self
}
pub fn media_sync_enabled(mut self, enable: bool) -> Self {
self.config.media_sync_enabled = Some(enable);
self
}
pub fn ssrc_demultiplexing_enabled(mut self, enable: bool) -> Self {
self.config.ssrc_demultiplexing_enabled = Some(enable);
self
}
pub fn csrc_management_enabled(mut self, enable: bool) -> Self {
self.config.csrc_management_enabled = enable;
self
}
pub fn header_extensions_enabled(mut self, enable: bool) -> Self {
self.config.header_extensions_enabled = enable;
self
}
pub fn header_extension_format(mut self, format: ExtensionFormat) -> Self {
self.config.header_extension_format = format;
self
}
pub fn transmit_buffer_config(mut self, config: TransmitBufferConfig) -> Self {
self.config.transmit_buffer_config = config;
self
}
pub fn buffer_limits(mut self, limits: BufferLimits) -> Self {
self.config.buffer_limits = limits;
self
}
pub fn high_performance_buffers_enabled(mut self, enabled: bool) -> Self {
self.config.high_performance_buffers_enabled = enabled;
self
}
pub fn rtp_session_buffer_config(mut self, config: RtpSessionBufferConfig) -> Self {
self.config.rtp_session_buffer_config = config;
self
}
pub fn rtp_transport_buffer_config(mut self, config: RtpTransportBufferConfig) -> Self {
self.config.rtp_transport_buffer_config = config;
self
}
pub fn frame_channel_capacity(mut self, capacity: usize) -> Self {
self.config.frame_channel_capacity = capacity;
self
}
pub fn build(self) -> Result<ServerConfig, crate::api::common::error::MediaTransportError> {
if self.config.max_clients == 0 {
return Err(crate::api::common::error::MediaTransportError::ConfigError(
"Maximum number of clients cannot be zero".to_string(),
));
}
Ok(self.config)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_buffer_tuning_preserves_existing_server_values() {
let config = ServerConfigBuilder::new().build().unwrap();
assert_eq!(config.frame_channel_capacity, 16);
assert_eq!(
config.rtp_session_buffer_config,
RtpSessionBufferConfig::default()
);
assert_eq!(
config.rtp_transport_buffer_config,
RtpTransportBufferConfig::default()
);
}
#[test]
fn builder_sets_buffer_tuning() {
let session_buffers = RtpSessionBufferConfig {
sender_channel_capacity: 8,
receiver_channel_capacity: 4,
event_channel_capacity: 16,
};
let transport_buffers = RtpTransportBufferConfig {
event_channel_capacity: 12,
recv_buffer_size: 2048,
rtcp_recv_buffer_size: 1024,
};
let config = ServerConfigBuilder::new()
.rtp_session_buffer_config(session_buffers)
.rtp_transport_buffer_config(transport_buffers)
.frame_channel_capacity(7)
.build()
.unwrap();
assert_eq!(config.rtp_session_buffer_config, session_buffers);
assert_eq!(config.rtp_transport_buffer_config, transport_buffers);
assert_eq!(config.frame_channel_capacity, 7);
}
}