Expand description
Room state, routing and media transport orchestration.
o-sfu-core bridges the server runtime, the pure o-sfu-router state machine
and the str0m-backed media transport. It keeps room admission, user media
intent and RTC worker details behind SfuCore and
MediaSession.
§Public Surface
preludecontains caller-facing configuration, media intent,SfuCoreandMediaSession.servercontains runtime construction, room integration, transport, diagnostics and metrics.- Fundamental identifiers and
Bitrateremain at the crate root.
§Architecture
server runtime
-> SfuCore::admit_user
-> MediaSession
-> room state and source policy
-> MediaTransport
-> RTC workersMediaTransport starts the worker threads
and binds their UDP sockets. Room operations release state locks before awaiting
transport work. Source policy maps layout intent, active-speaker observations
and receiver bandwidth to route activity and packet gates. Worker-local packet
loops then demultiplex UDP and forward RTP through those gates. The private
rtc::codec boundary contains capability projection plus codec-specific packet
inspection and rewrite, so source policy does not branch on payload details.
§Server Construction
The server builds one MediaTransport
from owner configuration and shared process services.
use std::{
net::{IpAddr, Ipv4Addr},
sync::Arc,
};
use o_sfu_core::{
prelude::{
Bitrate, CodecPreferences, MediaCodecFlags, RtcPortRange, RtcUdpIoBackend,
SessionBitrateLimits, VideoBitrateLimits,
},
server::{
metrics::RuntimeMetrics,
packet_sinks::RoomPacketSinkRegistry,
transport::{MediaTransport, MediaTransportConfig, MediaTransportDeps},
},
};
let config = MediaTransportConfig {
worker_count: 1,
announced_ip: IpAddr::V4(Ipv4Addr::LOCALHOST),
bitrate_limits: SessionBitrateLimits::new(
Bitrate::from_mbps(3),
Bitrate::from_mbps(3),
),
video_bitrate_limits: VideoBitrateLimits::default(),
rtc_port_range: RtcPortRange::new(40_000, 40_099),
rtc_udp_io_backend: RtcUdpIoBackend::Tokio,
codec_flags: MediaCodecFlags::default(),
codec_preferences: CodecPreferences::default(),
media_quality_interval: None,
};
let deps = MediaTransportDeps {
packet_sink_registry: Arc::new(RoomPacketSinkRegistry::default()),
metrics: Arc::new(RuntimeMetrics::default()),
};
let transport = MediaTransport::build(config, deps)?;
MediaTransport::build returns
after every worker runtime has bound its UDP socket. Session-local RTC state
remains lazy.
§Session Negotiation
Negotiation is serialized through &mut MediaSession. A publish received
while an offer is pending is queued. Applying the answer returns a follow-up
offer when that intent needs another SDP round.
use o_sfu_core::prelude::{
MediaSession, NegotiationOffer, SessionError, SourcePublishIntent,
};
async fn publish_source(
mut session: MediaSession,
intent: SourcePublishIntent,
) -> Result<(), SessionError> {
let Some(initial_offer) = session.establish().await? else {
return Ok(());
};
let initial_answer = exchange(initial_offer).await;
// Publish before answering so this intent queues behind the in-flight SDP round.
let _queued_without_offer = session.publish(intent).await?;
let Some(follow_up_offer) = session.answer(&initial_answer).await? else {
return Ok(());
};
let follow_up_answer = exchange(follow_up_offer).await;
let _next_offer = session.answer(&follow_up_answer).await?;
Ok(())
}Modules§
- engine 🔒
- Private media engine implementation tree.
- options 🔒
- prelude
- Caller-facing
o-sfu-coreAPI. - server
- Server-runtime integration surface.
- sfu 🔒
SfuCore::admit_userreturns oneMediaSessionper admitted room connection.
Structs§
- Bitrate
- Media bitrate stored as bits per second (not bytes per second).
- Connection
Id - unique identifier for a user’s transport connection within the server process
- Media
Worker Id - runtime-local identifier for one rtc media worker
- Room
Instance Id - Process-local generation tag for one room lifecycle.