use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::debug;
use crate::api::common::error::MediaTransportError;
use crate::{CsrcManager, CsrcMapping, RtpCsrc, RtpSsrc};
pub fn is_csrc_management_enabled(csrc_management_enabled: &Arc<AtomicBool>) -> bool {
csrc_management_enabled.load(Ordering::SeqCst)
}
pub async fn enable_csrc_management(
csrc_management_enabled: &Arc<AtomicBool>,
) -> Result<bool, MediaTransportError> {
if csrc_management_enabled.load(Ordering::SeqCst) {
return Ok(true);
}
csrc_management_enabled.store(true, Ordering::SeqCst);
debug!("Enabled CSRC management");
Ok(true)
}
pub async fn add_csrc_mapping(
csrc_management_enabled: &Arc<AtomicBool>,
csrc_manager: &Arc<Mutex<CsrcManager>>,
mapping: CsrcMapping,
) -> Result<(), MediaTransportError> {
if !csrc_management_enabled.load(Ordering::SeqCst) {
return Err(MediaTransportError::ConfigError(
"CSRC management is not enabled".to_string(),
));
}
let mut csrc_manager = csrc_manager.lock().await;
let mapping_clone = mapping.clone(); csrc_manager.add_mapping(mapping);
debug!("Added CSRC mapping: {:?}", mapping_clone);
Ok(())
}
pub async fn add_simple_csrc_mapping(
csrc_management_enabled: &Arc<AtomicBool>,
csrc_manager: &Arc<Mutex<CsrcManager>>,
original_ssrc: RtpSsrc,
csrc: RtpCsrc,
) -> Result<(), MediaTransportError> {
if !csrc_management_enabled.load(Ordering::SeqCst) {
return Err(MediaTransportError::ConfigError(
"CSRC management is not enabled".to_string(),
));
}
let mut csrc_manager = csrc_manager.lock().await;
csrc_manager.add_simple_mapping(original_ssrc, csrc);
debug!(
"Added simple CSRC mapping: {:08x} -> {:08x}",
original_ssrc, csrc
);
Ok(())
}
pub async fn remove_csrc_mapping_by_ssrc(
csrc_management_enabled: &Arc<AtomicBool>,
csrc_manager: &Arc<Mutex<CsrcManager>>,
original_ssrc: RtpSsrc,
) -> Result<Option<CsrcMapping>, MediaTransportError> {
if !csrc_management_enabled.load(Ordering::SeqCst) {
return Err(MediaTransportError::ConfigError(
"CSRC management is not enabled".to_string(),
));
}
let mut csrc_manager = csrc_manager.lock().await;
let removed = csrc_manager.remove_by_ssrc(original_ssrc);
if removed.is_some() {
debug!("Removed CSRC mapping for SSRC: {:08x}", original_ssrc);
}
Ok(removed)
}
pub async fn get_csrc_mapping_by_ssrc(
csrc_management_enabled: &Arc<AtomicBool>,
csrc_manager: &Arc<Mutex<CsrcManager>>,
original_ssrc: RtpSsrc,
) -> Result<Option<CsrcMapping>, MediaTransportError> {
if !csrc_management_enabled.load(Ordering::SeqCst) {
return Err(MediaTransportError::ConfigError(
"CSRC management is not enabled".to_string(),
));
}
let csrc_manager = csrc_manager.lock().await;
let mapping = csrc_manager.get_by_ssrc(original_ssrc).cloned();
Ok(mapping)
}
pub async fn get_all_csrc_mappings(
csrc_management_enabled: &Arc<AtomicBool>,
csrc_manager: &Arc<Mutex<CsrcManager>>,
) -> Result<Vec<CsrcMapping>, MediaTransportError> {
if !csrc_management_enabled.load(Ordering::SeqCst) {
return Err(MediaTransportError::ConfigError(
"CSRC management is not enabled".to_string(),
));
}
let csrc_manager = csrc_manager.lock().await;
let mappings = csrc_manager.get_all_mappings().to_vec();
Ok(mappings)
}
pub async fn get_active_csrcs(
csrc_management_enabled: &Arc<AtomicBool>,
csrc_manager: &Arc<Mutex<CsrcManager>>,
active_ssrcs: &[RtpSsrc],
) -> Result<Vec<RtpCsrc>, MediaTransportError> {
if !csrc_management_enabled.load(Ordering::SeqCst) {
return Err(MediaTransportError::ConfigError(
"CSRC management is not enabled".to_string(),
));
}
let csrc_manager = csrc_manager.lock().await;
let csrcs = csrc_manager.get_active_csrcs(active_ssrcs);
debug!(
"Got {} active CSRCs for {} active SSRCs",
csrcs.len(),
active_ssrcs.len()
);
Ok(csrcs)
}