o_sfu_core/engine/media_transport/
build.rs1use std::sync::Arc;
4
5use thiserror::Error;
6
7use super::{
8 MediaTransport, SourcePolicySignal,
9 config::{MediaTransportConfig, MediaTransportDeps},
10 rtc::{RtcWorker, RtpProfile},
11};
12use crate::{MediaWorkerId, RtcUdpIoBackend};
13
14const MEDIA_ID_STRIDE: u64 = 1_000_000_000;
20
21impl MediaTransport {
22 pub fn build(
33 config: MediaTransportConfig,
34 deps: MediaTransportDeps,
35 ) -> Result<Self, MediaTransportBuildError> {
36 if config.rtc_udp_io_backend == RtcUdpIoBackend::IoUring && !cfg!(target_os = "linux") {
37 return Err(MediaTransportBuildError::UnsupportedUdpIoBackend {
38 backend: config.rtc_udp_io_backend,
39 });
40 }
41 if config.worker_count == 0 {
42 return Err(MediaTransportBuildError::InvalidWorkerCount);
43 }
44 let worker_ranges = config
45 .rtc_port_range
46 .split_for_workers(config.worker_count)
47 .ok_or(MediaTransportBuildError::InvalidPortSplit {
48 worker_count: config.worker_count,
49 port_count: config.rtc_port_range.port_count(),
50 })?;
51 let profile = Arc::new(
52 RtpProfile::compile(config.codec_flags, config.codec_preferences)
53 .map_err(|_error| MediaTransportBuildError::InvalidRtpProfile)?,
54 );
55 let source_policy_signal = SourcePolicySignal::default();
56 let workers: Arc<[_]> = (0_u16..u16::MAX)
57 .zip(worker_ranges)
58 .map(|(worker_index, range)| {
59 RtcWorker::start(
62 &config,
63 Arc::clone(&profile),
64 range,
65 &deps,
66 source_policy_signal.clone(),
67 u64::from(worker_index) * MEDIA_ID_STRIDE,
68 MediaWorkerId::from_raw(usize::from(worker_index)),
69 )
70 .map_err(|_error| MediaTransportBuildError::WorkerStartup {
71 worker_index: usize::from(worker_index),
72 })
73 })
74 .collect::<Result<_, _>>()?;
75 Ok(Self {
76 workers,
77 profile,
78 metrics: deps.metrics,
79 #[cfg(test)]
80 media_control_batches: Arc::default(),
81 #[cfg(any(test, feature = "testing-transport"))]
82 source_diagnostics_requests: Arc::default(),
83 source_policy_signal,
84 })
85 }
86}
87
88#[derive(Debug, Error, Clone, Copy, PartialEq, Eq)]
90pub enum MediaTransportBuildError {
91 #[error("media transport worker count must be at least one")]
93 InvalidWorkerCount,
94 #[error(
96 "media transport cannot split {port_count} UDP ports across {worker_count} media workers"
97 )]
98 InvalidPortSplit {
99 worker_count: usize,
100 port_count: u16,
101 },
102 #[error("rtc UDP I/O backend `{backend}` is not supported on this target")]
104 UnsupportedUdpIoBackend { backend: RtcUdpIoBackend },
105 #[error("media transport RTP profile is invalid")]
107 InvalidRtpProfile,
108 #[error("media transport worker {worker_index} failed to start")]
110 WorkerStartup { worker_index: usize },
111}