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

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

Issue 2941553003: Reland "SelectSettings algorithm for audio constraints." (Closed)
Patch Set: fix test Created 3 years, 6 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>
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 basic_constraint_set, constrained_format.constrained_resolution(), 182 basic_constraint_set, constrained_format.constrained_resolution(),
183 constrained_format.constrained_frame_rate(), 183 constrained_format.constrained_frame_rate(),
184 capture_params.requested_format, expect_source_native_size); 184 capture_params.requested_format, expect_source_native_size);
185 185
186 return VideoCaptureSettings( 186 return VideoCaptureSettings(
187 candidate.device_id(), capture_params, candidate.noise_reduction(), 187 candidate.device_id(), capture_params, candidate.noise_reduction(),
188 track_adapter_settings, constrained_format.constrained_frame_rate().Min(), 188 track_adapter_settings, constrained_format.constrained_frame_rate().Min(),
189 constrained_format.constrained_frame_rate().Max()); 189 constrained_format.constrained_frame_rate().Max());
190 } 190 }
191 191
192 // Generic distance function between two numeric values. Based on the fitness
193 // distance function described in
194 // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance
195 double Distance(double value1, double value2) {
196 if (std::fabs(value1 - value2) <= blink::DoubleConstraint::kConstraintEpsilon)
197 return 0.0;
198
199 return std::fabs(value1 - value2) /
200 std::max(std::fabs(value1), std::fabs(value2));
201 }
202
203 // Returns a pair with the minimum and maximum aspect ratios supported by the 192 // Returns a pair with the minimum and maximum aspect ratios supported by the
204 // candidate format |constrained_format|, subject to given width and height 193 // candidate format |constrained_format|, subject to given width and height
205 // constraints. 194 // constraints.
206 void GetSourceAspectRatioRange(const ConstrainedFormat& constrained_format, 195 void GetSourceAspectRatioRange(const ConstrainedFormat& constrained_format,
207 const blink::LongConstraint& height_constraint, 196 const blink::LongConstraint& height_constraint,
208 const blink::LongConstraint& width_constraint, 197 const blink::LongConstraint& width_constraint,
209 double* min_source_aspect_ratio, 198 double* min_source_aspect_ratio,
210 double* max_source_aspect_ratio) { 199 double* max_source_aspect_ratio) {
211 long min_height = constrained_format.MinHeight(); 200 long min_height = constrained_format.MinHeight();
212 if (ConstraintHasMin(height_constraint)) 201 if (ConstraintHasMin(height_constraint))
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 (constraint_has_min && max_source_value < constraint_min) || 266 (constraint_has_min && max_source_value < constraint_min) ||
278 (constraint_has_min && constraint_has_max && 267 (constraint_has_min && constraint_has_max &&
279 constraint_min > constraint_max)) { 268 constraint_min > constraint_max)) {
280 if (failed_constraint_name) 269 if (failed_constraint_name)
281 *failed_constraint_name = constraint.GetName(); 270 *failed_constraint_name = constraint.GetName();
282 return HUGE_VAL; 271 return HUGE_VAL;
283 } 272 }
284 273
285 // If the source value exceeds the maximum requested, penalize. 274 // If the source value exceeds the maximum requested, penalize.
286 if (constraint_has_max && native_source_value > constraint_max) 275 if (constraint_has_max && native_source_value > constraint_max)
287 return Distance(native_source_value, constraint_max); 276 return NumericConstraintFitnessDistance(native_source_value,
277 constraint_max);
288 278
289 return 0.0; 279 return 0.0;
290 } 280 }
291 281
292 // Returns a custom distance function suitable for frame rate, given 282 // Returns a custom distance function suitable for frame rate, given
293 // a |constraint| and a candidate format |constrained_format|. 283 // a |constraint| and a candidate format |constrained_format|.
294 // A source can support track frame rates in the interval 284 // A source can support track frame rates in the interval
295 // [min_frame_rate, max_frame_rate], using frame-rate adjustments if 285 // [min_frame_rate, max_frame_rate], using frame-rate adjustments if
296 // necessary. If the candidate range and the constraint range are disjoint, 286 // necessary. If the candidate range and the constraint range are disjoint,
297 // return HUGE_VAL. 287 // return HUGE_VAL.
(...skipping 21 matching lines...) Expand all
319 (constraint_has_min && constraint_has_max && 309 (constraint_has_min && constraint_has_max &&
320 constraint_min > constraint_max)) { 310 constraint_min > constraint_max)) {
321 if (failed_constraint_name) 311 if (failed_constraint_name)
322 *failed_constraint_name = constraint.GetName(); 312 *failed_constraint_name = constraint.GetName();
323 return HUGE_VAL; 313 return HUGE_VAL;
324 } 314 }
325 315
326 // Compute the cost using the native rate. 316 // Compute the cost using the native rate.
327 if (constraint_has_max && 317 if (constraint_has_max &&
328 constrained_format.native_frame_rate() > constraint_max) 318 constrained_format.native_frame_rate() > constraint_max)
329 return Distance(constrained_format.native_frame_rate(), constraint_max); 319 return NumericConstraintFitnessDistance(
320 constrained_format.native_frame_rate(), constraint_max);
330 321
331 return 0.0; 322 return 0.0;
332 } 323 }
333 324
334 // Returns a custom distance function suitable for aspect ratio, given 325 // Returns a custom distance function suitable for aspect ratio, given
335 // the values for the aspect_ratio, width and height constraints, and a 326 // the values for the aspect_ratio, width and height constraints, and a
336 // candidate format |constrained_format|. 327 // candidate format |constrained_format|.
337 // A source can support track resolutions that range from 328 // A source can support track resolutions that range from
338 // min_width x min_height to max_width x max_height 329 // min_width x min_height to max_width x max_height
339 // where 330 // where
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 FormatSourceDistance(candidate.format(), constrained_format, 484 FormatSourceDistance(candidate.format(), constrained_format,
494 constraint_set, failed_constraint_name) + 485 constraint_set, failed_constraint_name) +
495 PowerLineFrequencyConstraintSourceDistance( 486 PowerLineFrequencyConstraintSourceDistance(
496 constraint_set.goog_power_line_frequency, 487 constraint_set.goog_power_line_frequency,
497 candidate.power_line_frequency(), failed_constraint_name) + 488 candidate.power_line_frequency(), failed_constraint_name) +
498 NoiseReductionConstraintSourceDistance( 489 NoiseReductionConstraintSourceDistance(
499 constraint_set.goog_noise_reduction, candidate.noise_reduction(), 490 constraint_set.goog_noise_reduction, candidate.noise_reduction(),
500 failed_constraint_name); 491 failed_constraint_name);
501 } 492 }
502 493
503 // Returns the fitness distance between |value| and |constraint|.
504 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
505 double StringConstraintFitnessDistance(
506 const blink::WebString& value,
507 const blink::StringConstraint& constraint) {
508 if (!constraint.HasIdeal())
509 return 0.0;
510
511 for (auto& ideal_value : constraint.Ideal()) {
512 if (value == ideal_value)
513 return 0.0;
514 }
515
516 return 1.0;
517 }
518
519 // Returns the fitness distance between |value| and |constraint| for 494 // Returns the fitness distance between |value| and |constraint| for
520 // resolution constraints (i.e., width and height). 495 // resolution constraints (i.e., width and height).
521 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 496 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
522 double ResolutionConstraintFitnessDistance( 497 double ResolutionConstraintFitnessDistance(
523 long value, 498 long value,
524 const blink::LongConstraint& constraint) { 499 const blink::LongConstraint& constraint) {
525 if (!constraint.HasIdeal()) 500 if (!constraint.HasIdeal())
526 return 0.0; 501 return 0.0;
527 502
528 // Source resolutions greater than ideal support the ideal value with 503 // Source resolutions greater than ideal support the ideal value with
529 // cropping. 504 // cropping.
530 if (value >= constraint.Ideal()) 505 if (value >= constraint.Ideal())
531 return 0.0; 506 return 0.0;
532 507
533 return Distance(value, constraint.Ideal()); 508 return NumericConstraintFitnessDistance(value, constraint.Ideal());
534 } 509 }
535 510
536 // Returns the fitness distance between |value| and |constraint| for 511 // Returns the fitness distance between |value| and |constraint| for
537 // resolution constraints (i.e., width and height), ignoring cropping. 512 // resolution constraints (i.e., width and height), ignoring cropping.
538 // This measures how well a native resolution supports the idea value. 513 // This measures how well a native resolution supports the idea value.
539 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 514 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
540 double ResolutionConstraintNativeFitnessDistance( 515 double ResolutionConstraintNativeFitnessDistance(
541 long value, 516 long value,
542 const blink::LongConstraint& constraint) { 517 const blink::LongConstraint& constraint) {
543 return constraint.HasIdeal() ? Distance(value, constraint.Ideal()) : 0.0; 518 return constraint.HasIdeal()
519 ? NumericConstraintFitnessDistance(value, constraint.Ideal())
520 : 0.0;
544 } 521 }
545 522
546 // Returns the fitness distance between a source resolution settings 523 // Returns the fitness distance between a source resolution settings
547 // and the aspectRatio constraint, taking into account resolution restrictions 524 // and the aspectRatio constraint, taking into account resolution restrictions
548 // on the source imposed by the width and height constraints. 525 // on the source imposed by the width and height constraints.
549 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 526 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
550 double AspectRatioConstraintFitnessDistance( 527 double AspectRatioConstraintFitnessDistance(
551 const ConstrainedFormat& constrained_format, 528 const ConstrainedFormat& constrained_format,
552 const blink::LongConstraint& height_constraint, 529 const blink::LongConstraint& height_constraint,
553 const blink::LongConstraint& width_constraint, 530 const blink::LongConstraint& width_constraint,
554 const blink::DoubleConstraint& aspect_ratio_constraint) { 531 const blink::DoubleConstraint& aspect_ratio_constraint) {
555 if (!aspect_ratio_constraint.HasIdeal()) 532 if (!aspect_ratio_constraint.HasIdeal())
556 return 0.0; 533 return 0.0;
557 534
558 double min_source_aspect_ratio; 535 double min_source_aspect_ratio;
559 double max_source_aspect_ratio; 536 double max_source_aspect_ratio;
560 GetSourceAspectRatioRange(constrained_format, height_constraint, 537 GetSourceAspectRatioRange(constrained_format, height_constraint,
561 width_constraint, &min_source_aspect_ratio, 538 width_constraint, &min_source_aspect_ratio,
562 &max_source_aspect_ratio); 539 &max_source_aspect_ratio);
563 540
564 // If the supported aspect ratio range does not include the ideal aspect 541 // If the supported aspect ratio range does not include the ideal aspect
565 // ratio, compute fitness using the spec formula. 542 // ratio, compute fitness using the spec formula.
566 if (max_source_aspect_ratio < 543 if (max_source_aspect_ratio <
567 aspect_ratio_constraint.Ideal() - 544 aspect_ratio_constraint.Ideal() -
568 blink::DoubleConstraint::kConstraintEpsilon) { 545 blink::DoubleConstraint::kConstraintEpsilon) {
569 return Distance(max_source_aspect_ratio, aspect_ratio_constraint.Ideal()); 546 return NumericConstraintFitnessDistance(max_source_aspect_ratio,
547 aspect_ratio_constraint.Ideal());
570 } 548 }
571 549
572 if (min_source_aspect_ratio > 550 if (min_source_aspect_ratio >
573 aspect_ratio_constraint.Ideal() + 551 aspect_ratio_constraint.Ideal() +
574 blink::DoubleConstraint::kConstraintEpsilon) { 552 blink::DoubleConstraint::kConstraintEpsilon) {
575 return Distance(min_source_aspect_ratio, aspect_ratio_constraint.Ideal()); 553 return NumericConstraintFitnessDistance(min_source_aspect_ratio,
554 aspect_ratio_constraint.Ideal());
576 } 555 }
577 556
578 // Otherwise, the ideal aspect ratio can be supported and the fitness is 0. 557 // Otherwise, the ideal aspect ratio can be supported and the fitness is 0.
579 return 0.0; 558 return 0.0;
580 } 559 }
581 560
582 // Returns the fitness distance between |value| and |constraint| for the 561 // Returns the fitness distance between |value| and |constraint| for the
583 // frameRate constraint. 562 // frameRate constraint.
584 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 563 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
585 double FrameRateConstraintFitnessDistance( 564 double FrameRateConstraintFitnessDistance(
586 double value, 565 double value,
587 const blink::DoubleConstraint& constraint) { 566 const blink::DoubleConstraint& constraint) {
588 if (!constraint.HasIdeal()) 567 if (!constraint.HasIdeal())
589 return 0.0; 568 return 0.0;
590 569
591 // Source frame rates greater than ideal support the ideal value using 570 // Source frame rates greater than ideal support the ideal value using
592 // frame-rate adjustment. 571 // frame-rate adjustment.
593 if (value >= 572 if (value >=
594 constraint.Ideal() - blink::DoubleConstraint::kConstraintEpsilon) { 573 constraint.Ideal() - blink::DoubleConstraint::kConstraintEpsilon) {
595 return 0.0; 574 return 0.0;
596 } 575 }
597 576
598 return Distance(value, constraint.Ideal()); 577 return NumericConstraintFitnessDistance(value, constraint.Ideal());
599 } 578 }
600 579
601 // Returns the fitness distance between |value| and |constraint| for the 580 // Returns the fitness distance between |value| and |constraint| for the
602 // frameRate constraint, ignoring frame-rate adjustment. 581 // frameRate constraint, ignoring frame-rate adjustment.
603 // It measures how well the native frame rate supports the ideal value. 582 // It measures how well the native frame rate supports the ideal value.
604 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 583 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
605 double FrameRateConstraintNativeFitnessDistance( 584 double FrameRateConstraintNativeFitnessDistance(
606 double value, 585 double value,
607 const blink::DoubleConstraint& constraint) { 586 const blink::DoubleConstraint& constraint) {
608 return constraint.HasIdeal() ? Distance(value, constraint.Ideal()) : 0.0; 587 return constraint.HasIdeal()
588 ? NumericConstraintFitnessDistance(value, constraint.Ideal())
589 : 0.0;
609 } 590 }
610 591
611 // Returns the fitness distance between |value| and |constraint| for the 592 // Returns the fitness distance between |value| and |constraint| for the
612 // googPowerLineFrequency constraint. 593 // googPowerLineFrequency constraint.
613 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. 594 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
614 double PowerLineFrequencyConstraintFitnessDistance( 595 double PowerLineFrequencyConstraintFitnessDistance(
615 long value, 596 long value,
616 const blink::LongConstraint& constraint) { 597 const blink::LongConstraint& constraint) {
617 if (!constraint.HasIdeal()) 598 if (!constraint.HasIdeal())
618 return 0.0; 599 return 0.0;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 // implementation choose a noise-reduction strategy. 709 // implementation choose a noise-reduction strategy.
729 double noise_reduction_distance = 710 double noise_reduction_distance =
730 candidate.noise_reduction() ? HUGE_VAL : 0.0; 711 candidate.noise_reduction() ? HUGE_VAL : 0.0;
731 distance_vector->push_back(noise_reduction_distance); 712 distance_vector->push_back(noise_reduction_distance);
732 713
733 // Prefer a resolution with area close to the default. 714 // Prefer a resolution with area close to the default.
734 int candidate_area = candidate.format().frame_size.GetArea(); 715 int candidate_area = candidate.format().frame_size.GetArea();
735 double resolution_distance = 716 double resolution_distance =
736 candidate_area == kDefaultResolutionArea 717 candidate_area == kDefaultResolutionArea
737 ? 0.0 718 ? 0.0
738 : Distance(candidate_area, kDefaultResolutionArea); 719 : NumericConstraintFitnessDistance(candidate_area,
720 kDefaultResolutionArea);
739 distance_vector->push_back(resolution_distance); 721 distance_vector->push_back(resolution_distance);
740 722
741 // Prefer a frame rate close to the default. 723 // Prefer a frame rate close to the default.
742 double frame_rate_distance = 724 double frame_rate_distance =
743 candidate.format().frame_rate == MediaStreamVideoSource::kDefaultFrameRate 725 candidate.format().frame_rate == MediaStreamVideoSource::kDefaultFrameRate
744 ? 0.0 726 ? 0.0
745 : Distance(candidate.format().frame_rate, 727 : NumericConstraintFitnessDistance(
746 MediaStreamVideoSource::kDefaultFrameRate); 728 candidate.format().frame_rate,
729 MediaStreamVideoSource::kDefaultFrameRate);
747 distance_vector->push_back(frame_rate_distance); 730 distance_vector->push_back(frame_rate_distance);
748 } 731 }
749 732
750 } // namespace 733 } // namespace
751 734
752 blink::WebString GetVideoKindForFormat( 735 blink::WebString GetVideoKindForFormat(
753 const media::VideoCaptureFormat& format) { 736 const media::VideoCaptureFormat& format) {
754 return (format.pixel_format == media::PIXEL_FORMAT_Y16) 737 return (format.pixel_format == media::PIXEL_FORMAT_Y16)
755 ? blink::WebString::FromASCII(kVideoKindDepth) 738 ? blink::WebString::FromASCII(kVideoKindDepth)
756 : blink::WebString::FromASCII(kVideoKindColor); 739 : blink::WebString::FromASCII(kVideoKindColor);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 } 861 }
879 } 862 }
880 863
881 if (!result.HasValue()) 864 if (!result.HasValue())
882 return VideoCaptureSettings(failed_constraint_name); 865 return VideoCaptureSettings(failed_constraint_name);
883 866
884 return result; 867 return result;
885 } 868 }
886 869
887 } // namespace content 870 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698