Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: content/renderer/media/media_stream_constraints_util_video_device.cc

Issue 2777703002: Introduce SelectSettings algorithm for MediaStream video tracks. (Closed)
Patch Set: static asserts Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/media_stream_constraints_util_video_device.h" 5 #include "content/renderer/media/media_stream_constraints_util_video_device.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "content/renderer/media/media_stream_constraints_util.h" 13 #include "content/renderer/media/media_stream_constraints_util.h"
14 #include "content/renderer/media/media_stream_constraints_util_sets.h"
14 #include "content/renderer/media/media_stream_video_source.h" 15 #include "content/renderer/media/media_stream_video_source.h"
15 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 16 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
16 #include "third_party/WebKit/public/platform/WebString.h" 17 #include "third_party/WebKit/public/platform/WebString.h"
17 18
18 namespace content { 19 namespace content {
19 20
20 namespace { 21 namespace {
21 22
22 // Number of default settings to be used as final tie-breaking criteria for 23 // Number of default settings to be used as final tie-breaking criteria for
23 // settings that are equally good at satisfying constraints: 24 // settings that are equally good at satisfying constraints:
(...skipping 19 matching lines...) Expand all
43 return blink::WebString::fromASCII("environment"); 44 return blink::WebString::fromASCII("environment");
44 case ::mojom::FacingMode::LEFT: 45 case ::mojom::FacingMode::LEFT:
45 return blink::WebString::fromASCII("left"); 46 return blink::WebString::fromASCII("left");
46 case ::mojom::FacingMode::RIGHT: 47 case ::mojom::FacingMode::RIGHT:
47 return blink::WebString::fromASCII("right"); 48 return blink::WebString::fromASCII("right");
48 default: 49 default:
49 return blink::WebString::fromASCII(""); 50 return blink::WebString::fromASCII("");
50 } 51 }
51 } 52 }
52 53
53 struct VideoDeviceCaptureSourceSettings { 54 struct Candidate {
54 public: 55 public:
55 VideoDeviceCaptureSourceSettings( 56 Candidate(const std::string& device_id,
56 const std::string& device_id, 57 const media::VideoCaptureFormat& format,
57 const media::VideoCaptureFormat& format, 58 ::mojom::FacingMode facing_mode,
58 ::mojom::FacingMode facing_mode, 59 media::PowerLineFrequency power_line_frequency,
59 media::PowerLineFrequency power_line_frequency, 60 const base::Optional<bool>& noise_reduction)
60 const rtc::Optional<bool>& noise_reduction)
61 : device_id_(device_id), 61 : device_id_(device_id),
62 format_(format), 62 format_(format),
63 facing_mode_(facing_mode), 63 facing_mode_(facing_mode),
64 power_line_frequency_(power_line_frequency), 64 power_line_frequency_(power_line_frequency),
65 noise_reduction_(noise_reduction) {} 65 noise_reduction_(noise_reduction) {}
66 66
67 VideoDeviceCaptureSourceSettings(
68 const VideoDeviceCaptureSourceSettings& other) = default;
69 VideoDeviceCaptureSourceSettings& operator=(
70 const VideoDeviceCaptureSourceSettings& other) = default;
71 VideoDeviceCaptureSourceSettings(VideoDeviceCaptureSourceSettings&& other) =
72 default;
73 VideoDeviceCaptureSourceSettings& operator=(
74 VideoDeviceCaptureSourceSettings&& other) = default;
75 ~VideoDeviceCaptureSourceSettings() = default;
76
77 // These accessor-like methods transform types to what Blink constraint 67 // These accessor-like methods transform types to what Blink constraint
78 // classes expect. 68 // classes expect.
79 blink::WebString GetFacingMode() const { return ToWebString(facing_mode_); } 69 blink::WebString GetFacingMode() const { return ToWebString(facing_mode_); }
80 long GetPowerLineFrequency() const { 70 long GetPowerLineFrequency() const {
81 return static_cast<long>(power_line_frequency_); 71 return static_cast<long>(power_line_frequency_);
82 } 72 }
83 blink::WebString GetDeviceId() const { 73 blink::WebString GetDeviceId() const {
84 return blink::WebString::fromASCII(device_id_.data()); 74 return blink::WebString::fromASCII(device_id_.data());
85 } 75 }
86 blink::WebString GetVideoKind() const { 76 blink::WebString GetVideoKind() const {
87 return GetVideoKindForFormat(format_); 77 return GetVideoKindForFormat(format_);
88 } 78 }
89 79
90 // Accessors. 80 // Accessors.
91 const media::VideoCaptureFormat& format() const { return format_; } 81 const media::VideoCaptureFormat& format() const { return format_; }
92 const std::string& device_id() const { return device_id_; } 82 const std::string& device_id() const { return device_id_; }
93 ::mojom::FacingMode facing_mode() const { return facing_mode_; } 83 ::mojom::FacingMode facing_mode() const { return facing_mode_; }
94 media::PowerLineFrequency power_line_frequency() const { 84 media::PowerLineFrequency power_line_frequency() const {
95 return power_line_frequency_; 85 return power_line_frequency_;
96 } 86 }
97 const rtc::Optional<bool>& noise_reduction() const { 87 const base::Optional<bool>& noise_reduction() const {
98 return noise_reduction_; 88 return noise_reduction_;
99 } 89 }
100 90
101 private: 91 private:
102 std::string device_id_; 92 std::string device_id_;
103 media::VideoCaptureFormat format_; 93 media::VideoCaptureFormat format_;
104 ::mojom::FacingMode facing_mode_; 94 ::mojom::FacingMode facing_mode_;
105 media::PowerLineFrequency power_line_frequency_; 95 media::PowerLineFrequency power_line_frequency_;
106 rtc::Optional<bool> noise_reduction_; 96 base::Optional<bool> noise_reduction_;
107 }; 97 };
108 98
109 // The ConstrainedFormat class keeps track of the effect of constraint sets on 99 // The ConstrainedFormat class keeps track of the effect of constraint sets on
110 // the range of values supported by a video-capture format while iterating over 100 // the range of values supported by a video-capture format while iterating over
111 // the constraint sets. 101 // the constraint sets.
112 // For example, suppose a device supports a width of 1024. Then, in principle, 102 // For example, suppose a device supports a width of 1024. Then, in principle,
113 // it can support any width below 1024 using cropping. 103 // it can support any width below 1024 using cropping.
114 // Suppose the first advanced constraint set requests a maximum width of 640, 104 // Suppose the first advanced constraint set requests a maximum width of 640,
115 // and the second advanced constraint set requests a minimum of 800. 105 // and the second advanced constraint set requests a minimum of 800.
116 // Separately, the camera supports both advanced sets. However, if the first 106 // Separately, the camera supports both advanced sets. However, if the first
117 // set is supported, the second set can no longer be supported because width can 107 // set is supported, the second set can no longer be supported because width can
118 // no longer exceed 640. The ConstrainedFormat class keeps track of this. 108 // no longer exceed 640. The ConstrainedFormat class keeps track of this.
119 class ConstrainedFormat { 109 class ConstrainedFormat {
120 public: 110 public:
121 explicit ConstrainedFormat(const media::VideoCaptureFormat& format) 111 explicit ConstrainedFormat(const media::VideoCaptureFormat& format)
122 : native_height_(format.frame_size.height()), 112 : native_height_(format.frame_size.height()),
123 min_height_(1),
124 max_height_(format.frame_size.height()),
125 native_width_(format.frame_size.width()), 113 native_width_(format.frame_size.width()),
126 min_width_(1),
127 max_width_(format.frame_size.width()),
128 native_frame_rate_(format.frame_rate), 114 native_frame_rate_(format.frame_rate),
129 min_frame_rate_(1), 115 constrained_resolution_(1,
130 max_frame_rate_(format.frame_rate) {} 116 format.frame_size.height(),
117 1,
118 format.frame_size.width(),
119 0.0,
120 HUGE_VAL),
121 constrained_frame_rate_(1, format.frame_rate) {}
131 122
132 long native_height() const { return native_height_; } 123 long native_height() const { return native_height_; }
133 long min_height() const { return min_height_; }
134 long max_height() const { return max_height_; }
135 long native_width() const { return native_width_; } 124 long native_width() const { return native_width_; }
136 long min_width() const { return min_width_; } 125 double native_frame_rate() const { return native_frame_rate_; }
137 long max_width() const { return max_width_; } 126 const ResolutionSet& constrained_resolution() const {
138 long native_frame_rate() const { return native_frame_rate_; } 127 return constrained_resolution_;
139 long min_frame_rate() const { return min_frame_rate_; } 128 }
140 long max_frame_rate() const { return max_frame_rate_; } 129 const NumericRangeSet<double>& constrained_frame_rate() const {
130 return constrained_frame_rate_;
131 }
141 132
142 void ApplyConstraintSet( 133 long MinHeight() const { return constrained_resolution_.min_height(); }
134 long MaxHeight() const { return constrained_resolution_.max_height(); }
135 long MinWidth() const { return constrained_resolution_.min_width(); }
136 long MaxWidth() const { return constrained_resolution_.max_width(); }
137 double MinAspectRatio() const {
138 return constrained_resolution_.min_aspect_ratio();
139 }
140 double MaxAspectRatio() const {
141 return constrained_resolution_.max_aspect_ratio();
142 }
143 double MinFrameRate() const { return constrained_frame_rate_.Min(); }
144 double MaxFrameRate() const { return constrained_frame_rate_.Max(); }
145
146 // Returns true if the application of |constraint_set| is successful and
147 // results in a nonempty set. Returns true otherwise.
148 bool ApplyConstraintSet(
143 const blink::WebMediaTrackConstraintSet& constraint_set) { 149 const blink::WebMediaTrackConstraintSet& constraint_set) {
144 if (ConstraintHasMin(constraint_set.width)) 150 constrained_resolution_ = constrained_resolution_.Intersection(
145 min_width_ = std::max(min_width_, ConstraintMin(constraint_set.width)); 151 ResolutionSet::FromConstraintSet(constraint_set));
146 if (ConstraintHasMax(constraint_set.width)) 152 constrained_frame_rate_ = constrained_frame_rate_.Intersection(
147 max_width_ = std::min(max_width_, ConstraintMax(constraint_set.width)); 153 NumericRangeSet<double>::FromConstraint(constraint_set.frameRate));
148 154 DCHECK(!constrained_resolution_.IsEmpty());
149 if (ConstraintHasMin(constraint_set.height)) 155 DCHECK(!constrained_frame_rate_.IsEmpty());
150 min_height_ = std::max(min_height_, ConstraintMin(constraint_set.height)); 156 return true;
151 if (ConstraintHasMax(constraint_set.height))
152 max_height_ = std::min(max_height_, ConstraintMax(constraint_set.height));
153
154 if (ConstraintHasMin(constraint_set.frameRate))
155 min_frame_rate_ =
156 std::max(min_frame_rate_, ConstraintMin(constraint_set.frameRate));
157 if (ConstraintHasMax(constraint_set.frameRate))
158 max_frame_rate_ =
159 std::min(max_frame_rate_, ConstraintMax(constraint_set.frameRate));
160 } 157 }
161 158
162 private: 159 private:
163 // Using long for compatibility with Blink constraint classes. 160 // Using long for compatibility with Blink constraint classes.
164 long native_height_; 161 long native_height_;
165 long min_height_;
166 long max_height_;
167 long native_width_; 162 long native_width_;
168 long min_width_;
169 long max_width_;
170 double native_frame_rate_; 163 double native_frame_rate_;
171 double min_frame_rate_; 164 ResolutionSet constrained_resolution_;
172 double max_frame_rate_; 165 NumericRangeSet<double> constrained_frame_rate_;
173 }; 166 };
174 167
175 VideoDeviceCaptureSourceSelectionResult ResultFromSettings( 168 VideoCaptureSettings ComputeVideoDeviceCaptureSettings(
176 const VideoDeviceCaptureSourceSettings& settings) { 169 const Candidate& candidate,
170 const ConstrainedFormat& constrained_format,
171 const blink::WebMediaTrackConstraintSet& basic_constraint_set) {
177 media::VideoCaptureParams capture_params; 172 media::VideoCaptureParams capture_params;
178 capture_params.requested_format = settings.format(); 173 capture_params.requested_format = candidate.format();
179 capture_params.power_line_frequency = settings.power_line_frequency(); 174 capture_params.power_line_frequency = candidate.power_line_frequency();
175 auto track_adapter_settings = SelectVideoTrackAdapterSettings(
176 basic_constraint_set, constrained_format.constrained_resolution(),
177 constrained_format.constrained_frame_rate(),
178 capture_params.requested_format);
180 179
181 return VideoDeviceCaptureSourceSelectionResult( 180 return VideoCaptureSettings(
182 settings.device_id(), settings.facing_mode(), capture_params, 181 candidate.device_id(), capture_params, candidate.noise_reduction(),
183 settings.noise_reduction()); 182 track_adapter_settings,
183 constrained_format.constrained_frame_rate().Min());
184 } 184 }
185 185
186 // Generic distance function between two numeric values. Based on the fitness 186 // Generic distance function between two numeric values. Based on the fitness
187 // distance function described in 187 // distance function described in
188 // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance 188 // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance
189 double Distance(double value1, double value2) { 189 double Distance(double value1, double value2) {
190 if (std::fabs(value1 - value2) <= blink::DoubleConstraint::kConstraintEpsilon) 190 if (std::fabs(value1 - value2) <= blink::DoubleConstraint::kConstraintEpsilon)
191 return 0.0; 191 return 0.0;
192 192
193 return std::fabs(value1 - value2) / 193 return std::fabs(value1 - value2) /
194 std::max(std::fabs(value1), std::fabs(value2)); 194 std::max(std::fabs(value1), std::fabs(value2));
195 } 195 }
196 196
197 // Returns a pair with the minimum and maximum aspect ratios supported by the 197 // Returns a pair with the minimum and maximum aspect ratios supported by the
198 // candidate format |constrained_format|, subject to given width and height 198 // candidate format |constrained_format|, subject to given width and height
199 // constraints. 199 // constraints.
200 void GetSourceAspectRatioRange(const ConstrainedFormat& constrained_format, 200 void GetSourceAspectRatioRange(const ConstrainedFormat& constrained_format,
201 const blink::LongConstraint& height_constraint, 201 const blink::LongConstraint& height_constraint,
202 const blink::LongConstraint& width_constraint, 202 const blink::LongConstraint& width_constraint,
203 double* min_source_aspect_ratio, 203 double* min_source_aspect_ratio,
204 double* max_source_aspect_ratio) { 204 double* max_source_aspect_ratio) {
205 long min_height = constrained_format.min_height(); 205 long min_height = constrained_format.MinHeight();
206 if (ConstraintHasMin(height_constraint)) 206 if (ConstraintHasMin(height_constraint))
207 min_height = std::max(min_height, ConstraintMin(height_constraint)); 207 min_height = std::max(min_height, ConstraintMin(height_constraint));
208 208
209 long max_height = constrained_format.max_height(); 209 long max_height = constrained_format.MaxHeight();
210 if (ConstraintHasMax(height_constraint)) 210 if (ConstraintHasMax(height_constraint))
211 max_height = std::min(max_height, ConstraintMax(height_constraint)); 211 max_height = std::min(max_height, ConstraintMax(height_constraint));
212 212
213 long min_width = constrained_format.min_width(); 213 long min_width = constrained_format.MinWidth();
214 if (ConstraintHasMin(width_constraint)) 214 if (ConstraintHasMin(width_constraint))
215 min_width = std::max(min_width, ConstraintMin(width_constraint)); 215 min_width = std::max(min_width, ConstraintMin(width_constraint));
216 216
217 long max_width = constrained_format.max_width(); 217 long max_width = constrained_format.MaxWidth();
218 if (ConstraintHasMax(width_constraint)) 218 if (ConstraintHasMax(width_constraint))
219 max_width = std::min(max_width, ConstraintMax(width_constraint)); 219 max_width = std::min(max_width, ConstraintMax(width_constraint));
220 220
221 *min_source_aspect_ratio = 221 *min_source_aspect_ratio = std::max(
222 constrained_format.MinAspectRatio(),
222 std::max(static_cast<double>(min_width) / static_cast<double>(max_height), 223 std::max(static_cast<double>(min_width) / static_cast<double>(max_height),
223 kMinSourceAspectRatio); 224 kMinSourceAspectRatio));
224 *max_source_aspect_ratio = 225 *max_source_aspect_ratio = std::min(
226 constrained_format.MaxAspectRatio(),
225 std::max(static_cast<double>(max_width) / static_cast<double>(min_height), 227 std::max(static_cast<double>(max_width) / static_cast<double>(min_height),
226 kMinSourceAspectRatio); 228 kMinSourceAspectRatio));
227 } 229 }
228 230
229 // Returns a custom distance between a string and a string constraint. 231 // Returns a custom distance between a string and a string constraint.
230 // Returns 0 if |value| satisfies |constraint|. HUGE_VAL otherwise. 232 // Returns 0 if |value| satisfies |constraint|. HUGE_VAL otherwise.
231 double StringConstraintSourceDistance(const blink::WebString& value, 233 double StringConstraintSourceDistance(const blink::WebString& value,
232 const blink::StringConstraint& constraint, 234 const blink::StringConstraint& constraint,
233 const char** failed_constraint_name) { 235 const char** failed_constraint_name) {
234 if (constraint.matches(value)) 236 if (constraint.matches(value))
235 return 0.0; 237 return 0.0;
236 238
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 double FrameRateConstraintSourceDistance( 296 double FrameRateConstraintSourceDistance(
295 const ConstrainedFormat& constrained_format, 297 const ConstrainedFormat& constrained_format,
296 const blink::DoubleConstraint& constraint, 298 const blink::DoubleConstraint& constraint,
297 const char** failed_constraint_name) { 299 const char** failed_constraint_name) {
298 bool constraint_has_min = ConstraintHasMin(constraint); 300 bool constraint_has_min = ConstraintHasMin(constraint);
299 double constraint_min = constraint_has_min ? ConstraintMin(constraint) : -1.0; 301 double constraint_min = constraint_has_min ? ConstraintMin(constraint) : -1.0;
300 bool constraint_has_max = ConstraintHasMax(constraint); 302 bool constraint_has_max = ConstraintHasMax(constraint);
301 double constraint_max = constraint_has_max ? ConstraintMax(constraint) : -1.0; 303 double constraint_max = constraint_has_max ? ConstraintMax(constraint) : -1.0;
302 304
303 if ((constraint_has_max && 305 if ((constraint_has_max &&
304 constrained_format.min_frame_rate() > 306 constrained_format.MinFrameRate() >
305 constraint_max + blink::DoubleConstraint::kConstraintEpsilon) || 307 constraint_max + blink::DoubleConstraint::kConstraintEpsilon) ||
306 (constraint_has_min && 308 (constraint_has_min &&
307 constrained_format.max_frame_rate() < 309 constrained_format.MaxFrameRate() <
308 constraint_min - blink::DoubleConstraint::kConstraintEpsilon)) { 310 constraint_min - blink::DoubleConstraint::kConstraintEpsilon)) {
309 if (failed_constraint_name) 311 if (failed_constraint_name)
310 *failed_constraint_name = constraint.name(); 312 *failed_constraint_name = constraint.name();
311 return HUGE_VAL; 313 return HUGE_VAL;
312 } 314 }
313 315
314 // Compute the cost using the native rate. 316 // Compute the cost using the native rate.
315 if (constraint_has_max && 317 if (constraint_has_max &&
316 constrained_format.native_frame_rate() > constraint_max) 318 constrained_format.native_frame_rate() > constraint_max)
317 return Distance(constrained_format.native_frame_rate(), constraint_max); 319 return Distance(constrained_format.native_frame_rate(), constraint_max);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 396
395 return 0.0; 397 return 0.0;
396 } 398 }
397 399
398 // Returns a custom distance function suitable for the googNoiseReduction 400 // Returns a custom distance function suitable for the googNoiseReduction
399 // constraint, given a |constraint| and a candidate value |value|. 401 // constraint, given a |constraint| and a candidate value |value|.
400 // The distance is HUGE_VAL if |candidate_value| cannot satisfy |constraint|. 402 // The distance is HUGE_VAL if |candidate_value| cannot satisfy |constraint|.
401 // Otherwise, the distance is zero. 403 // Otherwise, the distance is zero.
402 double NoiseReductionConstraintSourceDistance( 404 double NoiseReductionConstraintSourceDistance(
403 const blink::BooleanConstraint& constraint, 405 const blink::BooleanConstraint& constraint,
404 const rtc::Optional<bool>& value, 406 const base::Optional<bool>& value,
405 const char** failed_constraint_name) { 407 const char** failed_constraint_name) {
406 if (!constraint.hasExact()) 408 if (!constraint.hasExact())
407 return 0.0; 409 return 0.0;
408 410
409 if (value && *value == constraint.exact()) 411 if (value && *value == constraint.exact())
410 return 0.0; 412 return 0.0;
411 413
412 if (failed_constraint_name) 414 if (failed_constraint_name)
413 *failed_constraint_name = constraint.name(); 415 *failed_constraint_name = constraint.name();
414 return HUGE_VAL; 416 return HUGE_VAL;
(...skipping 20 matching lines...) Expand all
435 // |constraint_set| cannot be satisfied together with previous constraint sets, 437 // |constraint_set| cannot be satisfied together with previous constraint sets,
436 // but will not influence the numeric value returned if it is not infinite. 438 // but will not influence the numeric value returned if it is not infinite.
437 // Formats with lower distance satisfy |constraint_set| with lower resource 439 // Formats with lower distance satisfy |constraint_set| with lower resource
438 // usage. 440 // usage.
439 double FormatSourceDistance( 441 double FormatSourceDistance(
440 const media::VideoCaptureFormat& format, 442 const media::VideoCaptureFormat& format,
441 const ConstrainedFormat& constrained_format, 443 const ConstrainedFormat& constrained_format,
442 const blink::WebMediaTrackConstraintSet& constraint_set, 444 const blink::WebMediaTrackConstraintSet& constraint_set,
443 const char** failed_constraint_name) { 445 const char** failed_constraint_name) {
444 return ResolutionConstraintSourceDistance( 446 return ResolutionConstraintSourceDistance(
445 constrained_format.native_height(), 447 constrained_format.native_height(), constrained_format.MinHeight(),
446 constrained_format.min_height(), constrained_format.max_height(), 448 constrained_format.MaxHeight(), constraint_set.height,
447 constraint_set.height, failed_constraint_name) + 449 failed_constraint_name) +
448 ResolutionConstraintSourceDistance( 450 ResolutionConstraintSourceDistance(
449 constrained_format.native_width(), constrained_format.min_width(), 451 constrained_format.native_width(), constrained_format.MinWidth(),
450 constrained_format.max_width(), constraint_set.width, 452 constrained_format.MaxWidth(), constraint_set.width,
451 failed_constraint_name) + 453 failed_constraint_name) +
452 AspectRatioConstraintSourceDistance( 454 AspectRatioConstraintSourceDistance(
453 constrained_format, constraint_set.height, constraint_set.width, 455 constrained_format, constraint_set.height, constraint_set.width,
454 constraint_set.aspectRatio, failed_constraint_name) + 456 constraint_set.aspectRatio, failed_constraint_name) +
455 FrameRateConstraintSourceDistance(constrained_format, 457 FrameRateConstraintSourceDistance(constrained_format,
456 constraint_set.frameRate, 458 constraint_set.frameRate,
457 failed_constraint_name) + 459 failed_constraint_name) +
458 StringConstraintSourceDistance(GetVideoKindForFormat(format), 460 StringConstraintSourceDistance(GetVideoKindForFormat(format),
459 constraint_set.videoKind, 461 constraint_set.videoKind,
460 failed_constraint_name); 462 failed_constraint_name);
461 } 463 }
462 464
463 // Returns a custom distance between |constraint_set| and |candidate|, given 465 // Returns a custom distance between |constraint_set| and |candidate|, given
464 // that the configuration is already constrained by |constrained_format|. 466 // that the configuration is already constrained by |constrained_format|.
465 // |constrained_format| may cause the distance to be infinite if 467 // |constrained_format| may cause the distance to be infinite if
466 // |constraint_set| cannot be satisfied together with previous constraint sets, 468 // |constraint_set| cannot be satisfied together with previous constraint sets,
467 // but will not influence the numeric value returned if it is not infinite. 469 // but will not influence the numeric value returned if it is not infinite.
468 // Candidates with lower distance satisfy |constraint_set| with lower resource 470 // Candidates with lower distance satisfy |constraint_set| with lower resource
469 // usage. 471 // usage.
470 double CandidateSourceDistance( 472 double CandidateSourceDistance(
471 const VideoDeviceCaptureSourceSettings& candidate, 473 const Candidate& candidate,
472 const ConstrainedFormat& constrained_format, 474 const ConstrainedFormat& constrained_format,
473 const blink::WebMediaTrackConstraintSet& constraint_set, 475 const blink::WebMediaTrackConstraintSet& constraint_set,
474 const char** failed_constraint_name) { 476 const char** failed_constraint_name) {
475 return DeviceSourceDistance(candidate.device_id(), candidate.facing_mode(), 477 return DeviceSourceDistance(candidate.device_id(), candidate.facing_mode(),
476 constraint_set, failed_constraint_name) + 478 constraint_set, failed_constraint_name) +
477 FormatSourceDistance(candidate.format(), constrained_format, 479 FormatSourceDistance(candidate.format(), constrained_format,
478 constraint_set, failed_constraint_name) + 480 constraint_set, failed_constraint_name) +
479 PowerLineFrequencyConstraintSourceDistance( 481 PowerLineFrequencyConstraintSourceDistance(
480 constraint_set.googPowerLineFrequency, 482 constraint_set.googPowerLineFrequency,
481 candidate.power_line_frequency(), failed_constraint_name) + 483 candidate.power_line_frequency(), failed_constraint_name) +
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 if (value == constraint.ideal()) 608 if (value == constraint.ideal())
607 return 0.0; 609 return 0.0;
608 610
609 return 1.0; 611 return 1.0;
610 } 612 }
611 613
612 // Returns the fitness distance between |value| and |constraint| for the 614 // Returns the fitness distance between |value| and |constraint| for the
613 // googNoiseReduction constraint. 615 // googNoiseReduction constraint.
614 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 616 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
615 double NoiseReductionConstraintFitnessDistance( 617 double NoiseReductionConstraintFitnessDistance(
616 const rtc::Optional<bool>& value, 618 const base::Optional<bool>& value,
617 const blink::BooleanConstraint& constraint) { 619 const blink::BooleanConstraint& constraint) {
618 if (!constraint.hasIdeal()) 620 if (!constraint.hasIdeal())
619 return 0.0; 621 return 0.0;
620 622
621 if (value && value == constraint.ideal()) 623 if (value && value == constraint.ideal())
622 return 0.0; 624 return 0.0;
623 625
624 return 1.0; 626 return 1.0;
625 } 627 }
626 628
627 // Returns the fitness distance between |constraint_set| and |candidate| given 629 // Returns the fitness distance between |constraint_set| and |candidate| given
628 // that the configuration is already constrained by |constrained_format|. 630 // that the configuration is already constrained by |constrained_format|.
629 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 631 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
630 double CandidateFitnessDistance( 632 double CandidateFitnessDistance(
631 const VideoDeviceCaptureSourceSettings& candidate, 633 const Candidate& candidate,
632 const ConstrainedFormat& constrained_format, 634 const ConstrainedFormat& constrained_format,
633 const blink::WebMediaTrackConstraintSet& constraint_set) { 635 const blink::WebMediaTrackConstraintSet& constraint_set) {
634 DCHECK(std::isfinite(CandidateSourceDistance(candidate, constrained_format, 636 DCHECK(std::isfinite(CandidateSourceDistance(candidate, constrained_format,
635 constraint_set, nullptr))); 637 constraint_set, nullptr)));
636 double fitness = 0.0; 638 double fitness = 0.0;
637 fitness += AspectRatioConstraintFitnessDistance( 639 fitness += AspectRatioConstraintFitnessDistance(
638 constrained_format, constraint_set.height, constraint_set.width, 640 constrained_format, constraint_set.height, constraint_set.width,
639 constraint_set.aspectRatio); 641 constraint_set.aspectRatio);
640 fitness += StringConstraintFitnessDistance(candidate.GetDeviceId(), 642 fitness += StringConstraintFitnessDistance(candidate.GetDeviceId(),
641 constraint_set.deviceId); 643 constraint_set.deviceId);
642 fitness += StringConstraintFitnessDistance(candidate.GetFacingMode(), 644 fitness += StringConstraintFitnessDistance(candidate.GetFacingMode(),
643 constraint_set.facingMode); 645 constraint_set.facingMode);
644 fitness += StringConstraintFitnessDistance(candidate.GetVideoKind(), 646 fitness += StringConstraintFitnessDistance(candidate.GetVideoKind(),
645 constraint_set.videoKind); 647 constraint_set.videoKind);
646 fitness += PowerLineFrequencyConstraintFitnessDistance( 648 fitness += PowerLineFrequencyConstraintFitnessDistance(
647 candidate.GetPowerLineFrequency(), constraint_set.googPowerLineFrequency); 649 candidate.GetPowerLineFrequency(), constraint_set.googPowerLineFrequency);
648 fitness += NoiseReductionConstraintFitnessDistance( 650 fitness += NoiseReductionConstraintFitnessDistance(
649 candidate.noise_reduction(), constraint_set.googNoiseReduction); 651 candidate.noise_reduction(), constraint_set.googNoiseReduction);
650 // No need to pass minimum value to compute fitness for range-based 652 // No need to pass minimum value to compute fitness for range-based
651 // constraints because all candidates start out with the same minimum and are 653 // constraints because all candidates start out with the same minimum and are
652 // subject to the same constraints. 654 // subject to the same constraints.
653 fitness += ResolutionConstraintFitnessDistance( 655 fitness += ResolutionConstraintFitnessDistance(constrained_format.MaxHeight(),
654 constrained_format.max_height(), constraint_set.height); 656 constraint_set.height);
655 fitness += ResolutionConstraintFitnessDistance(constrained_format.max_width(), 657 fitness += ResolutionConstraintFitnessDistance(constrained_format.MaxWidth(),
656 constraint_set.width); 658 constraint_set.width);
657 fitness += FrameRateConstraintFitnessDistance( 659 fitness += FrameRateConstraintFitnessDistance(
658 constrained_format.max_frame_rate(), constraint_set.frameRate); 660 constrained_format.MaxFrameRate(), constraint_set.frameRate);
659 661
660 return fitness; 662 return fitness;
661 } 663 }
662 664
663 // Returns the native fitness distance between a candidate format and a 665 // Returns the native fitness distance between a candidate format and a
664 // constraint set. The returned value is the sum of the fitness distances for 666 // constraint set. The returned value is the sum of the fitness distances for
665 // the native values of settings that support a range of values (i.e., width, 667 // the native values of settings that support a range of values (i.e., width,
666 // height and frame rate). 668 // height and frame rate).
667 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 669 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
668 double CandidateNativeFitnessDistance( 670 double CandidateNativeFitnessDistance(
(...skipping 11 matching lines...) Expand all
680 } 682 }
681 683
682 using DistanceVector = std::vector<double>; 684 using DistanceVector = std::vector<double>;
683 685
684 // This function appends additional entries to |distance_vector| based on 686 // This function appends additional entries to |distance_vector| based on
685 // custom distance metrics between |candidate| and some default settings. 687 // custom distance metrics between |candidate| and some default settings.
686 // These entries are to be used as the final tie breaker for candidates that 688 // These entries are to be used as the final tie breaker for candidates that
687 // are equally good according to the spec and the custom distance functions 689 // are equally good according to the spec and the custom distance functions
688 // between candidates and constraints. 690 // between candidates and constraints.
689 void AppendDistanceFromDefault( 691 void AppendDistanceFromDefault(
690 const VideoDeviceCaptureSourceSettings& candidate, 692 const Candidate& candidate,
691 const VideoDeviceCaptureCapabilities& capabilities, 693 const VideoDeviceCaptureCapabilities& capabilities,
692 DistanceVector* distance_vector) { 694 DistanceVector* distance_vector) {
693 // Favor IDs that appear first in the enumeration. 695 // Favor IDs that appear first in the enumeration.
694 for (size_t i = 0; i < capabilities.device_capabilities.size(); ++i) { 696 for (size_t i = 0; i < capabilities.device_capabilities.size(); ++i) {
695 if (candidate.device_id() == 697 if (candidate.device_id() ==
696 capabilities.device_capabilities[i]->device_id) { 698 capabilities.device_capabilities[i]->device_id) {
697 distance_vector->push_back(i); 699 distance_vector->push_back(i);
698 break; 700 break;
699 } 701 }
700 } 702 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 : blink::WebString::fromASCII(kVideoKindColor); 741 : blink::WebString::fromASCII(kVideoKindColor);
740 } 742 }
741 743
742 VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities() = default; 744 VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities() = default;
743 VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities( 745 VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities(
744 VideoDeviceCaptureCapabilities&& other) = default; 746 VideoDeviceCaptureCapabilities&& other) = default;
745 VideoDeviceCaptureCapabilities::~VideoDeviceCaptureCapabilities() = default; 747 VideoDeviceCaptureCapabilities::~VideoDeviceCaptureCapabilities() = default;
746 VideoDeviceCaptureCapabilities& VideoDeviceCaptureCapabilities::operator=( 748 VideoDeviceCaptureCapabilities& VideoDeviceCaptureCapabilities::operator=(
747 VideoDeviceCaptureCapabilities&& other) = default; 749 VideoDeviceCaptureCapabilities&& other) = default;
748 750
749 VideoDeviceCaptureSourceSelectionResult:: 751 VideoCaptureSettings SelectSettingsVideoDeviceCapture(
750 VideoDeviceCaptureSourceSelectionResult()
751 : VideoDeviceCaptureSourceSelectionResult("") {}
752
753 VideoDeviceCaptureSourceSelectionResult::
754 VideoDeviceCaptureSourceSelectionResult(const char* failed_constraint_name)
755 : failed_constraint_name_(failed_constraint_name) {}
756
757 VideoDeviceCaptureSourceSelectionResult::
758 VideoDeviceCaptureSourceSelectionResult(
759 const std::string& device_id,
760 ::mojom::FacingMode facing_mode,
761 media::VideoCaptureParams capture_params,
762 rtc::Optional<bool> noise_reduction)
763 : failed_constraint_name_(nullptr),
764 device_id_(device_id),
765 facing_mode_(facing_mode),
766 capture_params_(capture_params),
767 noise_reduction_(noise_reduction) {}
768
769 VideoDeviceCaptureSourceSelectionResult::
770 VideoDeviceCaptureSourceSelectionResult(
771 const VideoDeviceCaptureSourceSelectionResult& other) = default;
772 VideoDeviceCaptureSourceSelectionResult::
773 VideoDeviceCaptureSourceSelectionResult(
774 VideoDeviceCaptureSourceSelectionResult&& other) = default;
775 VideoDeviceCaptureSourceSelectionResult::
776 ~VideoDeviceCaptureSourceSelectionResult() = default;
777 VideoDeviceCaptureSourceSelectionResult&
778 VideoDeviceCaptureSourceSelectionResult::operator=(
779 const VideoDeviceCaptureSourceSelectionResult& other) = default;
780 VideoDeviceCaptureSourceSelectionResult&
781 VideoDeviceCaptureSourceSelectionResult::operator=(
782 VideoDeviceCaptureSourceSelectionResult&& other) = default;
783
784 VideoDeviceCaptureSourceSelectionResult SelectVideoDeviceCaptureSourceSettings(
785 const VideoDeviceCaptureCapabilities& capabilities, 752 const VideoDeviceCaptureCapabilities& capabilities,
786 const blink::WebMediaConstraints& constraints) { 753 const blink::WebMediaConstraints& constraints) {
787 // This function works only if infinity is defined for the double type. 754 // This function works only if infinity is defined for the double type.
788 DCHECK(std::numeric_limits<double>::has_infinity); 755 DCHECK(std::numeric_limits<double>::has_infinity);
789 756
790 // A distance vector contains: 757 // A distance vector contains:
791 // a) For each advanced constraint set, a 0/1 value indicating if the 758 // a) For each advanced constraint set, a 0/1 value indicating if the
792 // candidate satisfies the corresponding constraint set. 759 // candidate satisfies the corresponding constraint set.
793 // b) Fitness distance for the candidate based on support for the ideal values 760 // b) Fitness distance for the candidate based on support for the ideal values
794 // of the basic constraint set. 761 // of the basic constraint set.
795 // c) A custom distance value based on how "well" a candidate satisfies each 762 // c) A custom distance value based on how "well" a candidate satisfies each
796 // constraint set, including basic and advanced sets. 763 // constraint set, including basic and advanced sets.
797 // d) Native fitness distance for the candidate based on support for the 764 // d) Native fitness distance for the candidate based on support for the
798 // ideal values of the basic constraint set using native values for 765 // ideal values of the basic constraint set using native values for
799 // settings that can support a range of values. 766 // settings that can support a range of values.
800 // e) A custom distance value based on how close the candidate is to default 767 // e) A custom distance value based on how close the candidate is to default
801 // settings. 768 // settings.
802 // Parts (a) and (b) are according to spec. Parts (c) to (e) are 769 // Parts (a) and (b) are according to spec. Parts (c) to (e) are
803 // implementation specific and used to break ties. 770 // implementation specific and used to break ties.
804 DistanceVector best_distance(2 * constraints.advanced().size() + 3 + 771 DistanceVector best_distance(2 * constraints.advanced().size() + 3 +
805 kNumDefaultDistanceEntries); 772 kNumDefaultDistanceEntries);
806 std::fill(best_distance.begin(), best_distance.end(), HUGE_VAL); 773 std::fill(best_distance.begin(), best_distance.end(), HUGE_VAL);
807 VideoDeviceCaptureSourceSelectionResult result; 774 VideoCaptureSettings result;
808 const char* failed_constraint_name = result.failed_constraint_name(); 775 const char* failed_constraint_name = result.failed_constraint_name();
809 776
810 for (auto& device : capabilities.device_capabilities) { 777 for (auto& device : capabilities.device_capabilities) {
811 double basic_device_distance = 778 double basic_device_distance =
812 DeviceSourceDistance(device->device_id, device->facing_mode, 779 DeviceSourceDistance(device->device_id, device->facing_mode,
813 constraints.basic(), &failed_constraint_name); 780 constraints.basic(), &failed_constraint_name);
814 if (!std::isfinite(basic_device_distance)) 781 if (!std::isfinite(basic_device_distance))
815 continue; 782 continue;
816 783
817 for (auto& format : device->formats) { 784 for (auto& format : device->formats) {
818 ConstrainedFormat constrained_format(format); 785 ConstrainedFormat constrained_format(format);
819 double basic_format_distance = 786 double basic_format_distance =
820 FormatSourceDistance(format, constrained_format, constraints.basic(), 787 FormatSourceDistance(format, constrained_format, constraints.basic(),
821 &failed_constraint_name); 788 &failed_constraint_name);
822 if (!std::isfinite(basic_format_distance)) 789 if (!std::isfinite(basic_format_distance))
823 continue; 790 continue;
824 constrained_format.ApplyConstraintSet(constraints.basic()); 791 constrained_format.ApplyConstraintSet(constraints.basic());
792 DCHECK(!constrained_format.constrained_resolution().IsEmpty());
793 DCHECK(!constrained_format.constrained_frame_rate().IsEmpty());
825 794
826 for (auto& power_line_frequency : capabilities.power_line_capabilities) { 795 for (auto& power_line_frequency : capabilities.power_line_capabilities) {
827 double basic_power_line_frequency_distance = 796 double basic_power_line_frequency_distance =
828 PowerLineFrequencyConstraintSourceDistance( 797 PowerLineFrequencyConstraintSourceDistance(
829 constraints.basic().googPowerLineFrequency, 798 constraints.basic().googPowerLineFrequency,
830 power_line_frequency, &failed_constraint_name); 799 power_line_frequency, &failed_constraint_name);
831 if (!std::isfinite(basic_power_line_frequency_distance)) 800 if (!std::isfinite(basic_power_line_frequency_distance))
832 continue; 801 continue;
833 802
834 for (auto& noise_reduction : 803 for (auto& noise_reduction :
835 capabilities.noise_reduction_capabilities) { 804 capabilities.noise_reduction_capabilities) {
836 double basic_noise_reduction_distance = 805 double basic_noise_reduction_distance =
837 NoiseReductionConstraintSourceDistance( 806 NoiseReductionConstraintSourceDistance(
838 constraints.basic().googNoiseReduction, noise_reduction, 807 constraints.basic().googNoiseReduction, noise_reduction,
839 &failed_constraint_name); 808 &failed_constraint_name);
840 if (!std::isfinite(basic_noise_reduction_distance)) 809 if (!std::isfinite(basic_noise_reduction_distance))
841 continue; 810 continue;
842 811
843 // The candidate satisfies the basic constraint set. 812 // The candidate satisfies the basic constraint set.
844 double candidate_basic_custom_distance = 813 double candidate_basic_custom_distance =
845 basic_device_distance + basic_format_distance + 814 basic_device_distance + basic_format_distance +
846 basic_power_line_frequency_distance + 815 basic_power_line_frequency_distance +
847 basic_noise_reduction_distance; 816 basic_noise_reduction_distance;
848 DCHECK(std::isfinite(candidate_basic_custom_distance)); 817 DCHECK(std::isfinite(candidate_basic_custom_distance));
849 818
850 // Temporary vector to save custom distances for advanced constraints. 819 // Temporary vector to save custom distances for advanced constraints.
851 // Custom distances must be added to the candidate distance vector 820 // Custom distances must be added to the candidate distance vector
852 // after all the spec-mandated values. 821 // after all the spec-mandated values.
853 DistanceVector advanced_custom_distance_vector; 822 DistanceVector advanced_custom_distance_vector;
854 VideoDeviceCaptureSourceSettings candidate( 823 Candidate candidate(device->device_id, format, device->facing_mode,
855 device->device_id, format, device->facing_mode, 824 power_line_frequency, noise_reduction);
856 power_line_frequency, noise_reduction);
857 DistanceVector candidate_distance_vector; 825 DistanceVector candidate_distance_vector;
858 // First criteria for valid candidates is satisfaction of advanced 826 // First criteria for valid candidates is satisfaction of advanced
859 // constraint sets. 827 // constraint sets.
860 for (const auto& advanced_set : constraints.advanced()) { 828 for (const auto& advanced_set : constraints.advanced()) {
861 double custom_distance = CandidateSourceDistance( 829 double custom_distance = CandidateSourceDistance(
862 candidate, constrained_format, advanced_set, nullptr); 830 candidate, constrained_format, advanced_set, nullptr);
863 advanced_custom_distance_vector.push_back(custom_distance); 831 advanced_custom_distance_vector.push_back(custom_distance);
864 double spec_distance = std::isfinite(custom_distance) ? 0 : 1; 832 double spec_distance = std::isfinite(custom_distance) ? 0 : 1;
865 candidate_distance_vector.push_back(spec_distance); 833 candidate_distance_vector.push_back(spec_distance);
866 if (std::isfinite(custom_distance)) 834 if (std::isfinite(custom_distance))
(...skipping 14 matching lines...) Expand all
881 candidate_distance_vector.push_back(CandidateNativeFitnessDistance( 849 candidate_distance_vector.push_back(CandidateNativeFitnessDistance(
882 constrained_format, constraints.basic())); 850 constrained_format, constraints.basic()));
883 851
884 // Final criteria are custom distances to default settings. 852 // Final criteria are custom distances to default settings.
885 AppendDistanceFromDefault(candidate, capabilities, 853 AppendDistanceFromDefault(candidate, capabilities,
886 &candidate_distance_vector); 854 &candidate_distance_vector);
887 855
888 DCHECK_EQ(best_distance.size(), candidate_distance_vector.size()); 856 DCHECK_EQ(best_distance.size(), candidate_distance_vector.size());
889 if (candidate_distance_vector < best_distance) { 857 if (candidate_distance_vector < best_distance) {
890 best_distance = candidate_distance_vector; 858 best_distance = candidate_distance_vector;
891 result = ResultFromSettings(candidate); 859 result = ComputeVideoDeviceCaptureSettings(
860 candidate, constrained_format, constraints.basic());
892 } 861 }
893 } 862 }
894 } 863 }
895 } 864 }
896 } 865 }
897 866
898 if (!result.HasValue()) 867 if (!result.HasValue())
899 return VideoDeviceCaptureSourceSelectionResult(failed_constraint_name); 868 return VideoCaptureSettings(failed_constraint_name);
900 869
901 return result; 870 return result;
902 } 871 }
903 872
904 } // namespace content 873 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698