xref: /webrtc/constraints/src/property.rs (revision 86143b07)
1 //! Constants identifying the properties of a [`MediaStreamTrack`][media_stream_track] object,
2 //! as defined in the ["Media Capture and Streams"][media_track_supported_constraints] spec.
3 //!
4 //! [media_stream_track]: https://www.w3.org/TR/mediacapture-streams/#mediastreamtrack
5 //! [media_track_supported_constraints]: https://www.w3.org/TR/mediacapture-streams/#dom-mediatracksupportedconstraints
6 
7 use std::{borrow::Cow, fmt::Display};
8 
9 #[cfg(feature = "serde")]
10 use serde::{Deserialize, Serialize};
11 
12 /// An identifier for a media track property.
13 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14 #[cfg_attr(feature = "serde", serde(transparent))]
15 #[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
16 pub struct MediaTrackProperty(Cow<'static, str>);
17 
18 impl From<&MediaTrackProperty> for MediaTrackProperty {
from(borrowed: &MediaTrackProperty) -> Self19     fn from(borrowed: &MediaTrackProperty) -> Self {
20         borrowed.clone()
21     }
22 }
23 
24 impl From<String> for MediaTrackProperty {
25     /// Creates a property from an owned representation of its name.
from(owned: String) -> Self26     fn from(owned: String) -> Self {
27         Self(Cow::Owned(owned))
28     }
29 }
30 
31 impl From<&str> for MediaTrackProperty {
32     /// Creates a property from an owned representation of its name.
33     ///
34     /// Use `MediaTrackProperty::named(str)` if your property name
35     /// is statically borrowed (i.e. `&'static str`).
from(borrowed: &str) -> Self36     fn from(borrowed: &str) -> Self {
37         Self(Cow::Owned(borrowed.to_owned()))
38     }
39 }
40 
41 impl Display for MediaTrackProperty {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result42     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43         f.write_str(&self.0)
44     }
45 }
46 
47 impl MediaTrackProperty {
48     /// Creates a property from a statically borrowed representation of its name.
named(name: &'static str) -> Self49     pub const fn named(name: &'static str) -> Self {
50         Self(Cow::Borrowed(name))
51     }
52 
53     /// The property's name.
name(&self) -> &str54     pub fn name(&self) -> &str {
55         &self.0
56     }
57 }
58 
59 /// Standard properties that apply to both, audio and video device types.
60 pub mod common {
61     use super::*;
62 
63     /// Names of common properties.
64     pub mod name {
65         use super::*;
66 
67         /// The identifier of the device generating the content of the track,
68         /// as defined in the [spec][spec].
69         ///
70         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-deviceid
71         pub static DEVICE_ID: MediaTrackProperty = MediaTrackProperty::named("deviceId");
72 
73         /// The document-unique group identifier for the device generating the content
74         /// of the track, as defined in the [spec][spec].
75         ///
76         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-groupid
77         pub static GROUP_ID: MediaTrackProperty = MediaTrackProperty::named("groupId");
78     }
79 
80     /// Names of common properties.
names() -> Vec<&'static MediaTrackProperty>81     pub fn names() -> Vec<&'static MediaTrackProperty> {
82         use self::name::*;
83 
84         vec![&DEVICE_ID, &GROUP_ID]
85     }
86 }
87 
88 /// Standard properties that apply only to audio device types.
89 pub mod audio_only {
90     use super::*;
91 
92     /// Names of audio-only properties.
93     pub mod name {
94         use super::*;
95 
96         /// Automatic gain control is often desirable on the input signal recorded
97         /// by the microphone, as defined in the [spec][spec].
98         ///
99         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-autogaincontrol
100         pub static AUTO_GAIN_CONTROL: MediaTrackProperty =
101             MediaTrackProperty::named("autoGainControl");
102 
103         /// The number of independent channels of sound that the audio data contains,
104         /// i.e. the number of audio samples per sample frame, as defined in the [spec][spec].
105         ///
106         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-channelcount
107         pub static CHANNEL_COUNT: MediaTrackProperty = MediaTrackProperty::named("channelCount");
108 
109         /// When one or more audio streams is being played in the processes of
110         /// various microphones, it is often desirable to attempt to remove
111         /// all the sound being played from the input signals recorded by the microphones.
112         /// This is referred to as echo cancellation, as defined in the [spec][spec].
113         ///
114         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-echocancellation
115         pub static ECHO_CANCELLATION: MediaTrackProperty =
116             MediaTrackProperty::named("echoCancellation");
117 
118         /// The latency or latency range, in seconds, as defined in the [spec][spec].
119         ///
120         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-latency
121         pub static LATENCY: MediaTrackProperty = MediaTrackProperty::named("latency");
122 
123         /// Noise suppression is often desirable on the input signal recorded by the microphone,
124         /// as defined in the [spec][spec].
125         ///
126         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-noisesuppression
127         pub static NOISE_SUPPRESSION: MediaTrackProperty =
128             MediaTrackProperty::named("noiseSuppression");
129 
130         /// The sample rate in samples per second for the audio data, as defined in the [spec][spec].
131         ///
132         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-samplerate
133         pub static SAMPLE_RATE: MediaTrackProperty = MediaTrackProperty::named("sampleRate");
134 
135         /// The linear sample size in bits. This constraint can only
136         /// be satisfied for audio devices that produce linear samples, as defined in the [spec][spec].
137         ///
138         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-samplesize
139         pub static SAMPLE_SIZE: MediaTrackProperty = MediaTrackProperty::named("sampleSize");
140     }
141 
142     /// Names of all audio-only properties.
names() -> Vec<&'static MediaTrackProperty>143     pub fn names() -> Vec<&'static MediaTrackProperty> {
144         use self::name::*;
145 
146         vec![
147             &AUTO_GAIN_CONTROL,
148             &CHANNEL_COUNT,
149             &ECHO_CANCELLATION,
150             &LATENCY,
151             &NOISE_SUPPRESSION,
152             &SAMPLE_RATE,
153             &SAMPLE_SIZE,
154         ]
155     }
156 }
157 
158 /// Standard properties that apply only to video device types.
159 pub mod video_only {
160     use super::*;
161 
162     /// Names of audio-only properties.
163     pub mod name {
164         use super::*;
165 
166         /// The exact aspect ratio (width in pixels divided by height in pixels,
167         /// represented as a double rounded to the tenth decimal place),
168         /// as defined in the [spec][spec].
169         ///
170         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-aspectratio
171         pub static ASPECT_RATIO: MediaTrackProperty = MediaTrackProperty::named("aspectRatio");
172 
173         /// The directions that the camera can face, as seen from the user's perspective,
174         /// as defined in the [spec][spec].
175         ///
176         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-facingmode
177         pub static FACING_MODE: MediaTrackProperty = MediaTrackProperty::named("facingMode");
178 
179         /// The exact frame rate (frames per second) or frame rate range,
180         /// as defined in the [spec][spec].
181         ///
182         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-framerate
183         pub static FRAME_RATE: MediaTrackProperty = MediaTrackProperty::named("frameRate");
184 
185         /// The height or height range, in pixels, as defined in the [spec][spec].
186         ///
187         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-height
188         pub static HEIGHT: MediaTrackProperty = MediaTrackProperty::named("height");
189 
190         /// The width or width range, in pixels, as defined in the [spec][spec].
191         ///
192         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-width
193         pub static WIDTH: MediaTrackProperty = MediaTrackProperty::named("width");
194 
195         /// The means by which the resolution can be derived by the client, as defined in the [spec][spec].
196         ///
197         /// In other words, whether the client is allowed to use cropping and downscaling on the camera output.
198         ///
199         /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-resizemode
200         pub static RESIZE_MODE: MediaTrackProperty = MediaTrackProperty::named("resizeMode");
201     }
202 
203     /// Names of all video-only properties.
names() -> Vec<&'static MediaTrackProperty>204     pub fn names() -> Vec<&'static MediaTrackProperty> {
205         use self::name::*;
206         vec![
207             &ASPECT_RATIO,
208             &FACING_MODE,
209             &FRAME_RATE,
210             &HEIGHT,
211             &WIDTH,
212             &RESIZE_MODE,
213         ]
214     }
215 }
216 
217 /// The union of all standard properties (i.e. common + audio + video).
218 pub mod all {
219     use super::*;
220 
221     /// Names of all properties.
222     pub mod name {
223         pub use super::audio_only::name::*;
224         pub use super::common::name::*;
225         pub use super::video_only::name::*;
226     }
227 
228     /// Names of all properties.
names() -> Vec<&'static MediaTrackProperty>229     pub fn names() -> Vec<&'static MediaTrackProperty> {
230         let mut all = vec![];
231         all.append(&mut self::common::names());
232         all.append(&mut self::audio_only::names());
233         all.append(&mut self::video_only::names());
234         all
235     }
236 }
237 
238 #[cfg(test)]
239 mod tests {
240     use super::*;
241 
242     type Subject = MediaTrackProperty;
243 
244     mod from {
245         use super::*;
246 
247         #[test]
owned()248         fn owned() {
249             let actuals = [Subject::from("string"), Subject::from("string".to_owned())];
250             let expected = MediaTrackProperty(Cow::Owned("string".to_owned()));
251 
252             for actual in actuals {
253                 assert_eq!(actual, expected);
254 
255                 // TODO: remove feature-gate, once stabilized:
256                 #[cfg(feature = "cow_is_borrowed")]
257                 assert!(actual.0.is_owned());
258             }
259         }
260 
261         #[test]
borrowed()262         fn borrowed() {
263             let actual = Subject::named("string");
264             let expected = MediaTrackProperty(Cow::Borrowed("string"));
265 
266             assert_eq!(actual, expected);
267 
268             // TODO: remove feature-gate, once stabilized:
269             #[cfg(feature = "cow_is_borrowed")]
270             assert!(actual.0.is_borrowed());
271         }
272     }
273 
274     #[test]
name()275     fn name() {
276         assert_eq!(Subject::named("string").name(), "string");
277     }
278 
279     #[test]
to_string()280     fn to_string() {
281         assert_eq!(Subject::named("string").to_string(), "string");
282     }
283 }
284 
285 #[cfg(feature = "serde")]
286 #[cfg(test)]
287 mod serde_tests {
288     use crate::macros::test_serde_symmetry;
289 
290     use super::*;
291 
292     type Subject = MediaTrackProperty;
293 
294     #[test]
is_symmetric()295     fn is_symmetric() {
296         let subject = Subject::named("string");
297         let json = serde_json::json!("string");
298 
299         test_serde_symmetry!(subject: subject, json: json);
300     }
301 }
302