1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
6 #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
7 
8 #include <string>
9 
10 #include "media/base/video_facing.h"
11 #include "media/capture/video_capture_types.h"
12 #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h"
13 #include "third_party/blink/renderer/modules/mediastream/video_track_adapter_settings.h"
14 #include "third_party/blink/renderer/modules/modules_export.h"
15 #include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
16 #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
17 #include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
18 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
19 
20 namespace blink {
21 
22 extern const double kMinDeviceCaptureFrameRate;
23 
24 // This class represents the output the SelectSettings algorithm for video
25 // constraints (see https://w3c.github.io/mediacapture-main/#dfn-selectsettings)
26 // The input to SelectSettings is a user-supplied constraints object, and its
27 // output is a set of implementation-specific settings that are used to
28 // configure other Chromium objects such as sources, tracks and sinks so that
29 // they work in the way indicated by the specification. VideoCaptureSettings may
30 // also be used to implement other constraints-related functionality, such as
31 // the getSettings() function.
32 // The following fields are used to control MediaStreamVideoSource objects:
33 //   * device_id: used for device selection and obtained from the deviceId
34 //   * capture_params: used to initialize video capture. Its values are obtained
35 //     from the width, height, aspectRatio, frame_rate, and googNoiseReduction
36 //     constraints.
37 // The following fields are used to control MediaStreamVideoTrack objects:
38 //   * track_adapter_settings: All track objects use a VideoTrackAdapter object
39 //     that may perform cropping and frame-rate adjustment. This field contains
40 //     the adapter settings suitable for the track the constraints are being
41 //     to. These settings are derived from the width, height, aspectRatio and
42 //     frameRate constraints.
43 // Some MediaStreamVideoSink objects (e.g. MediaStreamVideoWebRtcSink) require
44 // configuration derived from constraints that cannot be obtained from the
45 // source and track settings indicated above. The following fields are used
46 // to configure sinks:
47 //   * noise_reduction: used to control noise reduction for a screen-capture
48 //     track sent to a peer connection. Derive from the googNoiseReduction
49 //     constraint.
50 //   * min_frame_rate and max_frame_rate: used to control frame refreshes in
51 //     screen-capture tracks sent to a peer connection. Derived from the
52 //     frameRate constraint.
53 // If SelectSettings fails, the HasValue() method returns false and
54 // failed_constraint_name() returns the name of one of the (possibly multiple)
55 // constraints that could not be satisfied.
56 class MODULES_EXPORT VideoCaptureSettings {
57  public:
58   // Creates an object without value and with an empty failed constraint name.
59   VideoCaptureSettings();
60 
61   // Creates an object without value and with the given
62   // |failed_constraint_name|. Does not take ownership of
63   // |failed_constraint_name|, so it must point to a string that remains
64   // accessible. |failed_constraint_name| must be non-null.
65   explicit VideoCaptureSettings(const char* failed_constraint_name);
66 
67   // Creates an object with the given values.
68   VideoCaptureSettings(std::string device_id,
69                        media::VideoCaptureParams capture_params_,
70                        base::Optional<bool> noise_reduction_,
71                        const VideoTrackAdapterSettings& track_adapter_settings,
72                        base::Optional<double> min_frame_rate,
73                        base::Optional<double> max_frame_rate,
74                        base::Optional<double> pan = base::nullopt,
75                        base::Optional<double> tilt = base::nullopt,
76                        base::Optional<double> zoom = base::nullopt);
77 
78   VideoCaptureSettings(const VideoCaptureSettings& other);
79   VideoCaptureSettings& operator=(const VideoCaptureSettings& other);
80   VideoCaptureSettings(VideoCaptureSettings&& other);
81   VideoCaptureSettings& operator=(VideoCaptureSettings&& other);
82   ~VideoCaptureSettings();
83 
HasValue()84   bool HasValue() const { return !failed_constraint_name_; }
85 
86   // Convenience accessors for fields embedded in |capture_params_|.
Format()87   const media::VideoCaptureFormat& Format() const {
88     return capture_params_.requested_format;
89   }
Width()90   int Width() const {
91     DCHECK(HasValue());
92     return capture_params_.requested_format.frame_size.width();
93   }
Height()94   int Height() const {
95     DCHECK(HasValue());
96     return capture_params_.requested_format.frame_size.height();
97   }
FrameRate()98   float FrameRate() const {
99     DCHECK(HasValue());
100     return capture_params_.requested_format.frame_rate;
101   }
ResolutionChangePolicy()102   media::ResolutionChangePolicy ResolutionChangePolicy() const {
103     DCHECK(HasValue());
104     return capture_params_.resolution_change_policy;
105   }
106 
107   // Other accessors.
failed_constraint_name()108   const char* failed_constraint_name() const { return failed_constraint_name_; }
109 
device_id()110   const std::string& device_id() const {
111     DCHECK(HasValue());
112     return device_id_;
113   }
capture_params()114   const media::VideoCaptureParams& capture_params() const {
115     DCHECK(HasValue());
116     return capture_params_;
117   }
noise_reduction()118   const base::Optional<bool>& noise_reduction() const {
119     DCHECK(HasValue());
120     return noise_reduction_;
121   }
track_adapter_settings()122   const VideoTrackAdapterSettings& track_adapter_settings() const {
123     DCHECK(HasValue());
124     return track_adapter_settings_;
125   }
min_frame_rate()126   const base::Optional<double>& min_frame_rate() const {
127     DCHECK(HasValue());
128     return min_frame_rate_;
129   }
max_frame_rate()130   const base::Optional<double>& max_frame_rate() const {
131     DCHECK(HasValue());
132     return max_frame_rate_;
133   }
pan()134   const base::Optional<double>& pan() const {
135     DCHECK(HasValue());
136     return pan_;
137   }
tilt()138   const base::Optional<double>& tilt() const {
139     DCHECK(HasValue());
140     return tilt_;
141   }
zoom()142   const base::Optional<double>& zoom() const {
143     DCHECK(HasValue());
144     return zoom_;
145   }
146 
147  private:
148   const char* failed_constraint_name_;
149   std::string device_id_;
150   media::VideoCaptureParams capture_params_;
151   base::Optional<bool> noise_reduction_;
152   VideoTrackAdapterSettings track_adapter_settings_;
153   base::Optional<double> min_frame_rate_;
154   base::Optional<double> max_frame_rate_;
155   base::Optional<double> pan_;
156   base::Optional<double> tilt_;
157   base::Optional<double> zoom_;
158 };
159 
160 // This class represents the output the SelectSettings algorithm for audio
161 // constraints (see https://w3c.github.io/mediacapture-main/#dfn-selectsettings)
162 // The input to SelectSettings is a user-supplied constraints object, and its
163 // output is a set of implementation-specific settings that are used to
164 // configure other Chromium objects such as sources, tracks and sinks so that
165 // they work in the way indicated by the specification. AudioCaptureSettings may
166 // also be used to implement other constraints-related functionality, such as
167 // the getSettings() function.
168 // The following fields are used to control MediaStreamVideoSource objects:
169 //   * device_id: used for device selection and obtained from the deviceId
170 //   * device_parameters: these are the hardware parameters for the device
171 //     selected by SelectSettings. They can be used to verify that the
172 //     parameters with which the audio stream is actually created corresponds
173 //     to what SelectSettings selected. It can also be used to implement
174 //     getSettings() for device-related properties such as sampleRate and
175 //     channelCount.
176 // The following fields are used to control various audio features:
177 //   * disable_local_echo
178 //   * render_to_associated_sink
179 // The audio_properties field is used to control the audio-processing module,
180 // which provides features such as software-based echo cancellation.
181 // If SelectSettings fails, the HasValue() method returns false and
182 // failed_constraint_name() returns the name of one of the (possibly multiple)
183 // constraints that could not be satisfied.
184 class MODULES_EXPORT AudioCaptureSettings {
185  public:
186   enum class ProcessingType {
187     // System echo cancellation can be enabled, but all other processing is
188     // disabled.
189     kUnprocessed,
190     // System echo cancellation and audio mirroring can be enabled, but all
191     // other processing is disabled.
192     kNoApmProcessed,
193     // Processing is performed through WebRTC.
194     kApmProcessed
195   };
196 
197   // Creates an object without value and with an empty failed constraint name.
198   AudioCaptureSettings();
199 
200   // Creates an object without value and with the given
201   // |failed_constraint_name|. Does not take ownership of
202   // |failed_constraint_name|, so it must point to a string that remains
203   // accessible. |failed_constraint_name| must be non-null.
204   explicit AudioCaptureSettings(const char* failed_constraint_name);
205 
206   // Creates an object with the given values.
207   explicit AudioCaptureSettings(
208       std::string device_id,
209       const base::Optional<int>& requested_buffer_size,
210       bool disable_local_echo,
211       bool enable_automatic_output_device_selection,
212       ProcessingType processing_type,
213       const AudioProcessingProperties& audio_processing_properties);
214   AudioCaptureSettings(const AudioCaptureSettings& other);
215   AudioCaptureSettings& operator=(const AudioCaptureSettings& other);
216   AudioCaptureSettings(AudioCaptureSettings&& other);
217   AudioCaptureSettings& operator=(AudioCaptureSettings&& other);
218 
HasValue()219   bool HasValue() const { return !failed_constraint_name_; }
220 
221   // Accessors.
failed_constraint_name()222   const char* failed_constraint_name() const { return failed_constraint_name_; }
device_id()223   const std::string& device_id() const {
224     DCHECK(HasValue());
225     return device_id_;
226   }
requested_buffer_size()227   const base::Optional<int>& requested_buffer_size() const {
228     DCHECK(HasValue());
229     return requested_buffer_size_;
230   }
disable_local_echo()231   bool disable_local_echo() const {
232     DCHECK(HasValue());
233     return disable_local_echo_;
234   }
render_to_associated_sink()235   bool render_to_associated_sink() const {
236     DCHECK(HasValue());
237     return render_to_associated_sink_;
238   }
processing_type()239   ProcessingType processing_type() const {
240     DCHECK(HasValue());
241     return processing_type_;
242   }
audio_processing_properties()243   AudioProcessingProperties audio_processing_properties() const {
244     DCHECK(HasValue());
245     return audio_processing_properties_;
246   }
247 
248  private:
249   const char* failed_constraint_name_;
250   std::string device_id_;
251   base::Optional<int> requested_buffer_size_;
252   bool disable_local_echo_;
253   bool render_to_associated_sink_;
254   ProcessingType processing_type_;
255   AudioProcessingProperties audio_processing_properties_;
256 };
257 
258 // Method to get boolean value of constraint with |name| from constraints.
259 // Returns true if the constraint is specified in either mandatory or optional
260 // constraints.
261 MODULES_EXPORT bool GetConstraintValueAsBoolean(
262     const MediaConstraints& constraints,
263     const blink::BooleanConstraint MediaTrackConstraintSetPlatform::*picker,
264     bool* value);
265 
266 // Method to get int value of constraint with |name| from constraints.
267 // Returns true if the constraint is specified in either mandatory or Optional
268 // constraints.
269 MODULES_EXPORT bool GetConstraintValueAsInteger(
270     const MediaConstraints& constraints,
271     const blink::LongConstraint MediaTrackConstraintSetPlatform::*picker,
272     int* value);
273 
274 MODULES_EXPORT bool GetConstraintMinAsInteger(
275     const MediaConstraints& constraints,
276     const blink::LongConstraint MediaTrackConstraintSetPlatform::*picker,
277     int* value);
278 
279 MODULES_EXPORT bool GetConstraintMaxAsInteger(
280     const MediaConstraints& constraints,
281     const blink::LongConstraint MediaTrackConstraintSetPlatform::*picker,
282     int* value);
283 
284 // Method to get double precision value of constraint with |name| from
285 // constraints. Returns true if the constraint is specified in either mandatory
286 // or Optional constraints.
287 MODULES_EXPORT bool GetConstraintValueAsDouble(
288     const MediaConstraints& constraints,
289     const blink::DoubleConstraint MediaTrackConstraintSetPlatform::*picker,
290     double* value);
291 
292 // This function selects track settings from a set of candidate resolutions and
293 // frame rates, given the source video-capture format and ideal values.
294 // The output are settings for a VideoTrackAdapter, which can adjust the
295 // resolution and frame rate of the source, and consist of
296 // target width, height and frame rate, and minimum and maximum aspect ratio.
297 // * Minimum and maximum aspect ratios are taken from |resolution_set| and are
298 //   not affected by ideal values.
299 // * The selected frame rate is always the value within the |frame_rate_set|
300 //   range that is closest to the ideal frame rate (or closest to the source
301 //   frame rate if no ideal is supplied). If the chosen frame rate is greater
302 //   than or equal to the source's frame rate, a value of 0.0 is returned, which
303 //   means that there will be no frame-rate adjustment.
304 // * If |enable_rescale| is false, no target width and height are computed.
305 // * If |enable_rescale| is true, the target width and height are selected using
306 //   the ResolutionSet::SelectClosestPointToIdeal function, using ideal values
307 //   for the width, height and aspectRatio properties from
308 //   |basic_constraint_set| and using the source's width and height as the
309 //   default resolution. The width and height returned by
310 //   SelectClosestPointToIdeal are rounded to the nearest int. For more details,
311 //   see the documentation for ResolutionSet::SelectClosestPointToIdeal.
312 // Note that this function ignores the min/max/exact values from
313 // |basic_constraint_set|. Only the ideal values for the width, height,
314 // aspectRatio and frameRate are used.
315 // This function has undefined behavior if any of |resolution_set| or
316 // |frame_rate_set| are empty.
317 MODULES_EXPORT VideoTrackAdapterSettings SelectVideoTrackAdapterSettings(
318     const MediaTrackConstraintSetPlatform& basic_constraint_set,
319     const media_constraints::ResolutionSet& resolution_set,
320     const media_constraints::NumericRangeSet<double>& frame_rate_set,
321     const media::VideoCaptureFormat& source_format,
322     bool enable_rescale);
323 
324 // Generic distance function between two values for numeric constraints. Based
325 // on the fitness-distance function described in
326 // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance
327 MODULES_EXPORT double NumericConstraintFitnessDistance(double value1,
328                                                        double value2);
329 
330 // Fitness distance between |value| and |constraint|.
331 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
332 double StringConstraintFitnessDistance(
333     const blink::WebString& value,
334     const blink::StringConstraint& constraint);
335 
336 // This method computes capabilities for a video source based on the given
337 // |formats|. |facing_mode| is valid only in case of video device capture.
338 MODULES_EXPORT MediaStreamSource::Capabilities
339 ComputeCapabilitiesForVideoSource(
340     const String& device_id,
341     const media::VideoCaptureFormats& formats,
342     media::VideoFacingMode facing_mode,
343     bool is_device_capture,
344     const base::Optional<std::string>& group_id = base::nullopt);
345 
346 }  // namespace blink
347 
348 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
349