Crates.io | rvoip-media-core |
lib.rs | rvoip-media-core |
version | 0.1.26 |
created_at | 2025-07-03 07:48:29.436131+00 |
updated_at | 2025-08-15 17:49:46.122498+00 |
description | Media processing and codec support for the rvoip stack |
homepage | https://github.com/eisenzopf/rvoip |
repository | https://github.com/eisenzopf/rvoip |
max_upload_size | |
id | 1735968 |
size | 1,232,683 |
The media-core
library provides comprehensive media processing and audio management capabilities for the rvoip VoIP stack. It handles all media-level operations including codec management, advanced audio processing, quality monitoring, and multi-party conference mixing while integrating seamlessly with session-core
(SIP signaling) and rtp-core
(RTP transport).
rtp-core
session-core
rtp-core
session-core
(media-core provides capabilities)The Media Core sits at the heart of the media processing stack, providing intelligent audio processing and session coordination:
┌─────────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────────┤
│ rvoip-session-core │
├─────────────────────────────────────────┤
│ rvoip-media-core ⬅️ YOU ARE HERE
├─────────────────────────────────────────┤
│ rvoip-rtp-core │
├─────────────────────────────────────────┤
│ Network Layer │
└─────────────────────────────────────────┘
Clean separation of concerns across the rvoip stack:
┌─────────────────┐ Media Capabilities ┌─────────────────┐
│ │ ◄──────────────────────── │ │
│ session-core │ │ media-core │
│ (SIP Signaling) │ ──────────────────────► │ (Processing) │
│ │ Media Session Mgmt │ │
└─────────────────┘ └─────────────────┘
│
│ Media Streams
▼
┌─────────────────┐
│ rtp-core │
│ (Transport) │
└─────────────────┘
use rvoip_media_core::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Create media engine configuration
let config = MediaEngineConfig::builder()
.enable_advanced_processing(true)
.enable_performance_optimizations(true)
.build();
// Create and start media engine
let engine = MediaEngine::new(config).await?;
engine.start().await?;
// Create media session for SIP dialog
let dialog_id = DialogId::new("call-123");
let params = MediaSessionParams::builder()
.audio_only()
.preferred_codec(PayloadType::PCMU)
.enable_processing(true)
.advanced_aec_config(AdvancedAecConfig::default())
.advanced_agc_config(AdvancedAgcConfig::default())
.build();
let session = engine.create_media_session(dialog_id, params).await?;
// Get codec capabilities for SDP negotiation
let capabilities = engine.get_supported_codecs();
println!("Supported codecs: {:?}", capabilities);
// Process audio with advanced algorithms
let audio_frame = AudioFrame::new(samples, 16000, 1, timestamp);
let processed = session.process_audio(audio_frame).await?;
// Monitor quality metrics
let metrics = session.get_quality_metrics().await;
println!("MOS score: {:.1}, Packet loss: {:.1}%",
metrics.mos_score, metrics.packet_loss_percent);
Ok(())
}
use rvoip_media_core::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Configure advanced audio processing
let aec_config = AdvancedAecConfig::builder()
.filter_length(512)
.adaptation_rate(0.1)
.enable_comfort_noise(true)
.build();
let agc_config = AdvancedAgcConfig::builder()
.target_level_dbfs(-23.0)
.compression_ratio(3.0)
.enable_multiband(true)
.build();
let vad_config = AdvancedVadConfig::builder()
.enable_spectral_analysis(true)
.adaptive_threshold(true)
.build();
let processing_config = AudioProcessingConfig::builder()
.advanced_aec_config(aec_config)
.advanced_agc_config(agc_config)
.advanced_vad_config(vad_config)
.enable_simd_optimizations(true)
.build();
// Create processor with advanced algorithms
let processor = AudioProcessor::new(processing_config)?;
// Process audio with professional-grade algorithms
let input_frame = AudioFrame::new(samples, 16000, 1, timestamp);
let output_frame = processor.process_capture_audio(&input_frame)?;
// Advanced processing provides:
// - 16.4 dB better echo cancellation
// - 2.6x more consistent gain control
// - Spectral voice activity detection
Ok(())
}
use rvoip_media_core::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Create media session controller with conference support
let controller = MediaSessionController::with_conference_support().await?;
// Create media sessions for participants
let alice_dialog = DialogId::new("alice");
let bob_dialog = DialogId::new("bob");
let charlie_dialog = DialogId::new("charlie");
// Start media sessions
controller.start_media(alice_dialog.clone(), media_config()).await?;
controller.start_media(bob_dialog.clone(), media_config()).await?;
controller.start_media(charlie_dialog.clone(), media_config()).await?;
// Add participants to conference
controller.add_to_conference(alice_dialog.clone()).await?;
controller.add_to_conference(bob_dialog.clone()).await?;
controller.add_to_conference(charlie_dialog.clone()).await?;
// Process conference audio (N-1 mixing for each participant)
let alice_audio = AudioFrame::new(alice_samples, 8000, 1, timestamp);
controller.process_conference_audio(alice_dialog, alice_audio).await?;
// Conference automatically mixes audio from Bob and Charlie for Alice
// (excluding Alice's own voice to prevent echo)
// Monitor conference statistics
let stats = controller.get_conference_stats().await?;
println!("Active participants: {}, Total mixes: {}",
stats.active_participants, stats.total_mixes);
Ok(())
}
use rvoip_media_core::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Configure high-performance processing
let performance_config = PerformanceConfig::builder()
.enable_zero_copy(true)
.enable_simd_optimizations(true)
.enable_frame_pooling(true)
.frame_pool_size(64)
.build();
let config = MediaEngineConfig::builder()
.performance(performance_config)
.build();
let engine = MediaEngine::new(config).await?;
// Create session with performance optimizations
let session = engine.create_media_session(dialog_id, params).await?;
// Process with zero-copy architecture
// - 1.7-2.1x speedup from zero-copy operations
// - 4.2-12.6x speedup from object pooling
// - Sub-microsecond frame operations
let processed = session.process_audio_zero_copy(audio_frame).await?;
// Monitor performance metrics
let metrics = session.get_performance_metrics().await;
println!("Processing time: {}ns, Pool efficiency: {:.1}%",
metrics.avg_processing_time_ns, metrics.pool_efficiency * 100.0);
Ok(())
}
use rvoip_media_core::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Create transcoding session
let transcoder = Transcoder::new().await?;
// Configure transcoding between different codecs
let session_config = TranscodingSessionConfig::builder()
.input_codec(CodecType::PCMU)
.output_codec(CodecType::Opus)
.enable_format_conversion(true)
.build();
let session_id = transcoder.create_session(session_config).await?;
// Transcode audio in real-time
let pcmu_frame = AudioFrame::new(pcmu_samples, 8000, 1, timestamp);
let opus_frame = transcoder.transcode(session_id, pcmu_frame).await?;
// Supports all codec combinations:
// G.711 (PCMU/PCMA) ↔ Opus ↔ G.729
// with automatic format conversion
// Monitor transcoding performance
let stats = transcoder.get_session_stats(session_id).await?;
println!("Transcoding latency: {}μs, Quality: MOS {:.1}",
stats.avg_latency_us, stats.output_quality_mos);
Ok(())
}
The library provides cutting-edge audio processing algorithms competitive with commercial solutions:
The media-core library implements production-ready audio muting that maintains RTP flow by sending silence packets instead of dropping RTP transmission. This approach ensures compatibility with NAT traversal, firewalls, and all SIP endpoints.
use rvoip_media_core::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
let controller = MediaSessionController::new();
let dialog_id = DialogId::new("call-123");
// Start media session
controller.start_media(dialog_id.clone(), config).await?;
// Mute audio - RTP continues with silence packets
controller.set_audio_muted(&dialog_id, true).await?;
// Audio frames are now replaced with silence before encoding
// This maintains:
// - Continuous RTP sequence numbers and timestamps
// - NAT binding keepalive (prevents timeout)
// - Remote endpoint connectivity
// - Codec state consistency
// Check mute status
let is_muted = controller.is_audio_muted(&dialog_id).await?;
// Unmute to resume normal audio
controller.set_audio_muted(&dialog_id, false).await?;
Ok(())
}
Technical Implementation:
RtpSessionWrapper
encode_and_send_audio_frame()
Key Benefits:
Run the comprehensive test suite:
# Run all tests
cargo test -p rvoip-media-core
# Run with advanced processing features
cargo test -p rvoip-media-core --features "advanced-processing"
# Run performance benchmarks
cargo test -p rvoip-media-core --release -- --ignored benchmark
# Run specific test suites
cargo test -p rvoip-media-core audio_processing
cargo test -p rvoip-media-core conference_mixing
cargo test -p rvoip-media-core zero_copy_performance
The library includes comprehensive examples demonstrating all features:
# Basic media engine usage
cargo run --example basic_usage
# Advanced audio processing demonstration
cargo run --example processing_demo
# Echo cancellation showcase
cargo run --example aec_demo
# Quality monitoring example
cargo run --example quality_demo
# Conference mixing demonstration
RUST_LOG=info cargo run --example conference_demo
# Performance validation
cargo run --release --example performance_comparison
The library provides comprehensive error handling with categorized error types:
use rvoip_media_core::Error;
match media_result {
Err(Error::CodecNotSupported(codec)) => {
log::error!("Unsupported codec: {}", codec);
attempt_codec_fallback().await?;
}
Err(Error::ProcessingFailed(details)) => {
log::warn!("Audio processing failed: {}", details);
if error.is_recoverable() {
retry_with_basic_processing().await?;
}
}
Err(Error::SessionNotFound(session_id)) => {
log::info!("Session {} not found, creating new", session_id);
create_new_session(session_id).await?;
}
Ok(result) => {
// Handle success
}
}
Contributions are welcome! Please see the main rvoip contributing guidelines for details.
For media-core specific contributions:
This project is licensed under either of
at your option.