Skip to main content

o_sfu/config/
codec_preferences.rs

1use anyhow::{Result, anyhow, ensure};
2use o_sfu_core::prelude::{AudioCodecPreference, CodecPreferences, VideoCodecPreference};
3
4use super::env::Env;
5
6pub(super) fn load_codec_preferences(env: &Env<'_>) -> Result<CodecPreferences> {
7    let audio = match env.var::<String>("CODEC_AUDIO_PREFERENCE").optional()? {
8        Some(value) => parse_codec_list(&value, "CODEC_AUDIO_PREFERENCE", audio_codec_preference)?,
9        None => Vec::new(),
10    };
11    let video = match env.var::<String>("CODEC_VIDEO_PREFERENCE").optional()? {
12        Some(value) => parse_codec_list(&value, "CODEC_VIDEO_PREFERENCE", video_codec_preference)?,
13        None => Vec::new(),
14    };
15    Ok(CodecPreferences::default()
16        .with_audio_order(&audio)
17        .with_video_order(&video))
18}
19
20fn parse_codec_list<T>(
21    value: &str,
22    env_key: &str,
23    parse_codec: impl Fn(&str) -> Option<T>,
24) -> Result<Vec<T>>
25where
26    T: PartialEq,
27{
28    let mut codecs = Vec::new();
29    for raw_codec in value.split(',') {
30        let codec_name = raw_codec.trim();
31        ensure!(
32            !codec_name.is_empty(),
33            "{env_key} cannot contain empty entries"
34        );
35        let codec = parse_codec(codec_name)
36            .ok_or_else(|| anyhow!("{env_key} contains unsupported codec `{codec_name}`"))?;
37        ensure!(
38            !codecs.contains(&codec),
39            "{env_key} cannot contain duplicate codec `{codec_name}`"
40        );
41        codecs.push(codec);
42    }
43    Ok(codecs)
44}
45
46fn audio_codec_preference(codec_name: &str) -> Option<AudioCodecPreference> {
47    CodecPreferences::DEFAULT_AUDIO
48        .into_iter()
49        .find(|codec| codec_name.eq_ignore_ascii_case(codec.wire_name()))
50}
51
52fn video_codec_preference(codec_name: &str) -> Option<VideoCodecPreference> {
53    CodecPreferences::DEFAULT_VIDEO
54        .into_iter()
55        .find(|codec| codec_name.eq_ignore_ascii_case(codec.wire_name()))
56}
57
58#[cfg(test)]
59#[path = "TESTS/codec_preferences.rs"]
60mod tests;