xref: /webrtc/constraints/examples/native.rs (revision ce739920)
1 use std::iter::FromIterator;
2 
3 use webrtc_constraints::{
4     algorithms::{
5         select_settings_candidates, ClosestToIdealPolicy, DeviceInformationExposureMode,
6         TieBreakingPolicy,
7     },
8     property::all::name::*,
9     AdvancedMediaTrackConstraints, MandatoryMediaTrackConstraints, MediaTrackConstraintSet,
10     MediaTrackConstraints, MediaTrackSettings, MediaTrackSupportedConstraints, ResizeMode,
11     ResolvedValueConstraint, ResolvedValueRangeConstraint, ValueConstraint, ValueRangeConstraint,
12 };
13 
main()14 fn main() {
15     let supported_constraints =
16         MediaTrackSupportedConstraints::from_iter(vec![&DEVICE_ID, &HEIGHT, &WIDTH, &RESIZE_MODE]);
17 
18     let possible_settings = vec![
19         MediaTrackSettings::from_iter([
20             (&DEVICE_ID, "480p".into()),
21             (&HEIGHT, 480.into()),
22             (&WIDTH, 720.into()),
23             (&RESIZE_MODE, ResizeMode::crop_and_scale().into()),
24         ]),
25         MediaTrackSettings::from_iter([
26             (&DEVICE_ID, "720p".into()),
27             (&HEIGHT, 720.into()),
28             (&WIDTH, 1280.into()),
29             (&RESIZE_MODE, ResizeMode::crop_and_scale().into()),
30         ]),
31         MediaTrackSettings::from_iter([
32             (&DEVICE_ID, "1080p".into()),
33             (&HEIGHT, 1080.into()),
34             (&WIDTH, 1920.into()),
35             (&RESIZE_MODE, ResizeMode::none().into()),
36         ]),
37         MediaTrackSettings::from_iter([
38             (&DEVICE_ID, "1440p".into()),
39             (&HEIGHT, 1440.into()),
40             (&WIDTH, 2560.into()),
41             (&RESIZE_MODE, ResizeMode::none().into()),
42         ]),
43         MediaTrackSettings::from_iter([
44             (&DEVICE_ID, "2160p".into()),
45             (&HEIGHT, 2160.into()),
46             (&WIDTH, 3840.into()),
47             (&RESIZE_MODE, ResizeMode::none().into()),
48         ]),
49     ];
50 
51     let constraints = MediaTrackConstraints {
52         mandatory: MandatoryMediaTrackConstraints::from_iter([
53             (
54                 &WIDTH,
55                 ValueRangeConstraint::Constraint(ResolvedValueRangeConstraint::default().max(2560))
56                     .into(),
57             ),
58             (
59                 &HEIGHT,
60                 ValueRangeConstraint::Constraint(ResolvedValueRangeConstraint::default().max(1440))
61                     .into(),
62             ),
63             // Unsupported constraint, which should thus get ignored:
64             (
65                 &FRAME_RATE,
66                 ValueRangeConstraint::Constraint(
67                     ResolvedValueRangeConstraint::default().exact(30.0),
68                 )
69                 .into(),
70             ),
71         ]),
72         advanced: AdvancedMediaTrackConstraints::from_iter([
73             // The first advanced constraint set of "exact 800p" does not match
74             // any candidate and should thus get ignored by the algorithm:
75             MediaTrackConstraintSet::from_iter([(
76                 &HEIGHT,
77                 ValueRangeConstraint::Constraint(
78                     ResolvedValueRangeConstraint::default().exact(800),
79                 )
80                 .into(),
81             )]),
82             // The second advanced constraint set of "no resizing" does match
83             // candidates and should thus be applied by the algorithm:
84             MediaTrackConstraintSet::from_iter([(
85                 &RESIZE_MODE,
86                 ValueConstraint::Constraint(
87                     ResolvedValueConstraint::default().exact(ResizeMode::none()),
88                 )
89                 .into(),
90             )]),
91         ]),
92     };
93 
94     // Resolve bare values to proper constraints:
95     let resolved_constraints = constraints.into_resolved();
96 
97     // Sanitize constraints, removing empty and unsupported constraints:
98     let sanitized_constraints = resolved_constraints.to_sanitized(&supported_constraints);
99 
100     let candidates = select_settings_candidates(
101         &possible_settings,
102         &sanitized_constraints,
103         DeviceInformationExposureMode::Exposed,
104     )
105     .unwrap();
106 
107     // Specify a tie-breaking policy
108     //
109     // A couple of basic policies are provided batteries-included,
110     // but for more sophisticated needs you can implement your own `TieBreakingPolicy`:
111     let tie_breaking_policy =
112         ClosestToIdealPolicy::new(possible_settings[2].clone(), &supported_constraints);
113 
114     let actual = tie_breaking_policy.select_candidate(candidates);
115 
116     let expected = &possible_settings[2];
117 
118     assert_eq!(actual, expected);
119 }
120