use crate::{
algorithms::FitnessDistance, constraints::SanitizedAdvancedMediaTrackConstraints,
MediaTrackSettings,
};
pub(super) fn apply_advanced_constraints<'a>(
mut candidates: Vec<(&'a MediaTrackSettings, f64)>,
advanced_constraints: &SanitizedAdvancedMediaTrackConstraints,
) -> Vec<(&'a MediaTrackSettings, f64)> {
let mut selected_candidates = Vec::with_capacity(candidates.len());
for advanced_constraint_set in advanced_constraints.iter() {
for (candidate, fitness_distance) in candidates.iter() {
if advanced_constraint_set.fitness_distance(candidate).is_ok() {
selected_candidates.push((*candidate, *fitness_distance));
}
}
if !selected_candidates.is_empty() {
candidates.clear();
std::mem::swap(&mut candidates, &mut selected_candidates);
}
}
candidates
}
#[cfg(test)]
mod tests {
use std::iter::FromIterator;
use crate::{
property::all::name::*, MediaTrackSupportedConstraints, ResizeMode,
ResolvedAdvancedMediaTrackConstraints, ResolvedMediaTrackConstraintSet,
ResolvedValueConstraint, ResolvedValueRangeConstraint,
};
use super::*;
#[test]
fn overconstrained() {
let supported_constraints = MediaTrackSupportedConstraints::from_iter(vec![
&DEVICE_ID,
&HEIGHT,
&WIDTH,
&RESIZE_MODE,
]);
let settings = vec![
MediaTrackSettings::from_iter([(&DEVICE_ID, "foo".into())]),
MediaTrackSettings::from_iter([(&DEVICE_ID, "bar".into())]),
];
let candidates: Vec<_> = settings
.iter()
.map(|settings| (settings, 42.0))
.collect();
let constraints = ResolvedAdvancedMediaTrackConstraints::from_iter([
ResolvedMediaTrackConstraintSet::from_iter([(
&DEVICE_ID,
ResolvedValueConstraint::default()
.exact("bazblee".to_owned())
.into(),
)]),
]);
let sanitized_constraints = constraints.to_sanitized(&supported_constraints);
let actual: Vec<_> = apply_advanced_constraints(candidates, &sanitized_constraints)
.into_iter()
.map(|(settings, _)| settings)
.collect();
let expected: Vec<_> = settings.iter().collect();
assert_eq!(actual, expected);
}
#[test]
fn constrained() {
let supported_constraints = MediaTrackSupportedConstraints::from_iter(vec![
&DEVICE_ID,
&HEIGHT,
&WIDTH,
&RESIZE_MODE,
]);
let settings = vec![
MediaTrackSettings::from_iter([
(&DEVICE_ID, "480p".into()),
(&HEIGHT, 480.into()),
(&WIDTH, 720.into()),
(&RESIZE_MODE, ResizeMode::crop_and_scale().into()),
]),
MediaTrackSettings::from_iter([
(&DEVICE_ID, "720p".into()),
(&HEIGHT, 720.into()),
(&WIDTH, 1280.into()),
(&RESIZE_MODE, ResizeMode::crop_and_scale().into()),
]),
MediaTrackSettings::from_iter([
(&DEVICE_ID, "1080p".into()),
(&HEIGHT, 1080.into()),
(&WIDTH, 1920.into()),
(&RESIZE_MODE, ResizeMode::none().into()),
]),
MediaTrackSettings::from_iter([
(&DEVICE_ID, "1440p".into()),
(&HEIGHT, 1440.into()),
(&WIDTH, 2560.into()),
(&RESIZE_MODE, ResizeMode::none().into()),
]),
MediaTrackSettings::from_iter([
(&DEVICE_ID, "2160p".into()),
(&HEIGHT, 2160.into()),
(&WIDTH, 3840.into()),
(&RESIZE_MODE, ResizeMode::none().into()),
]),
];
let candidates: Vec<_> = settings.iter().map(|settings| (settings, 42.0)).collect();
let constraints = ResolvedAdvancedMediaTrackConstraints::from_iter([
ResolvedMediaTrackConstraintSet::from_iter([(
&HEIGHT,
ResolvedValueRangeConstraint::default().exact(800).into(),
)]),
ResolvedMediaTrackConstraintSet::from_iter([(
&RESIZE_MODE,
ResolvedValueConstraint::default()
.exact(ResizeMode::none())
.into(),
)]),
ResolvedMediaTrackConstraintSet::from_iter([(
&HEIGHT,
ResolvedValueRangeConstraint::default().max(1440).into(),
)]),
]);
let sanitized_constraints = constraints.to_sanitized(&supported_constraints);
let actual: Vec<_> = apply_advanced_constraints(candidates, &sanitized_constraints)
.into_iter()
.map(|(settings, _)| settings)
.collect();
let expected = vec![&settings[2], &settings[3]];
assert_eq!(actual, expected);
}
}