| OLD | NEW |
| 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_video_source.h" | 14 #include "content/renderer/media/media_stream_video_source.h" |
| 15 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" | 15 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" |
| 16 #include "third_party/WebKit/public/platform/WebString.h" | 16 #include "third_party/WebKit/public/platform/WebString.h" |
| 17 | 17 |
| 18 namespace content { | 18 namespace content { |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 // Number of default settings to be used as final tie-breaking criteria for | 22 // Number of default settings to be used as final tie-breaking criteria for |
| 23 // settings that are equally good at satisfying constraints: | 23 // settings that are equally good at satisfying constraints: |
| 24 // device ID, power-line frequency, resolution and frame rate. | 24 // device ID, power-line frequency, noise reduction, resolution and frame rate. |
| 25 const int kNumDefaultDistanceEntries = 4; | 25 const int kNumDefaultDistanceEntries = 5; |
| 26 | 26 |
| 27 // The default resolution to be preferred as tie-breaking criterion. | 27 // The default resolution to be preferred as tie-breaking criterion. |
| 28 const int kDefaultResolutionArea = MediaStreamVideoSource::kDefaultWidth * | 28 const int kDefaultResolutionArea = MediaStreamVideoSource::kDefaultWidth * |
| 29 MediaStreamVideoSource::kDefaultHeight; | 29 MediaStreamVideoSource::kDefaultHeight; |
| 30 | 30 |
| 31 // The minimum aspect ratio to be supported by sources. | 31 // The minimum aspect ratio to be supported by sources. |
| 32 const double kMinSourceAspectRatio = 0.05; | 32 const double kMinSourceAspectRatio = 0.05; |
| 33 | 33 |
| 34 // VideoKind enum values. See https://w3c.github.io/mediacapture-depth. | 34 // VideoKind enum values. See https://w3c.github.io/mediacapture-depth. |
| 35 const char kVideoKindColor[] = "color"; | 35 const char kVideoKindColor[] = "color"; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 53 struct VideoDeviceCaptureSourceSettings { | 53 struct VideoDeviceCaptureSourceSettings { |
| 54 public: | 54 public: |
| 55 VideoDeviceCaptureSourceSettings() | 55 VideoDeviceCaptureSourceSettings() |
| 56 : facing_mode_(::mojom::FacingMode::NONE), | 56 : facing_mode_(::mojom::FacingMode::NONE), |
| 57 power_line_frequency_(media::PowerLineFrequency::FREQUENCY_DEFAULT) {} | 57 power_line_frequency_(media::PowerLineFrequency::FREQUENCY_DEFAULT) {} |
| 58 | 58 |
| 59 VideoDeviceCaptureSourceSettings( | 59 VideoDeviceCaptureSourceSettings( |
| 60 const std::string& device_id, | 60 const std::string& device_id, |
| 61 const media::VideoCaptureFormat& format, | 61 const media::VideoCaptureFormat& format, |
| 62 ::mojom::FacingMode facing_mode, | 62 ::mojom::FacingMode facing_mode, |
| 63 media::PowerLineFrequency power_line_frequency) | 63 media::PowerLineFrequency power_line_frequency, |
| 64 const rtc::Optional<bool>& noise_reduction) |
| 64 : device_id_(device_id), | 65 : device_id_(device_id), |
| 65 format_(format), | 66 format_(format), |
| 66 facing_mode_(facing_mode), | 67 facing_mode_(facing_mode), |
| 67 power_line_frequency_(power_line_frequency) {} | 68 power_line_frequency_(power_line_frequency), |
| 69 noise_reduction_(noise_reduction) {} |
| 68 | 70 |
| 69 VideoDeviceCaptureSourceSettings( | 71 VideoDeviceCaptureSourceSettings( |
| 70 const VideoDeviceCaptureSourceSettings& other) = default; | 72 const VideoDeviceCaptureSourceSettings& other) = default; |
| 71 VideoDeviceCaptureSourceSettings& operator=( | 73 VideoDeviceCaptureSourceSettings& operator=( |
| 72 const VideoDeviceCaptureSourceSettings& other) = default; | 74 const VideoDeviceCaptureSourceSettings& other) = default; |
| 73 VideoDeviceCaptureSourceSettings(VideoDeviceCaptureSourceSettings&& other) = | 75 VideoDeviceCaptureSourceSettings(VideoDeviceCaptureSourceSettings&& other) = |
| 74 default; | 76 default; |
| 75 VideoDeviceCaptureSourceSettings& operator=( | 77 VideoDeviceCaptureSourceSettings& operator=( |
| 76 VideoDeviceCaptureSourceSettings&& other) = default; | 78 VideoDeviceCaptureSourceSettings&& other) = default; |
| 77 ~VideoDeviceCaptureSourceSettings() = default; | 79 ~VideoDeviceCaptureSourceSettings() = default; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 92 return GetVideoKindForFormat(format_); | 94 return GetVideoKindForFormat(format_); |
| 93 } | 95 } |
| 94 | 96 |
| 95 // Accessors. | 97 // Accessors. |
| 96 const media::VideoCaptureFormat& format() const { return format_; } | 98 const media::VideoCaptureFormat& format() const { return format_; } |
| 97 const std::string& device_id() const { return device_id_; } | 99 const std::string& device_id() const { return device_id_; } |
| 98 ::mojom::FacingMode facing_mode() const { return facing_mode_; } | 100 ::mojom::FacingMode facing_mode() const { return facing_mode_; } |
| 99 media::PowerLineFrequency power_line_frequency() const { | 101 media::PowerLineFrequency power_line_frequency() const { |
| 100 return power_line_frequency_; | 102 return power_line_frequency_; |
| 101 } | 103 } |
| 104 const rtc::Optional<bool>& noise_reduction() const { |
| 105 return noise_reduction_; |
| 106 } |
| 102 | 107 |
| 103 private: | 108 private: |
| 104 std::string device_id_; | 109 std::string device_id_; |
| 105 media::VideoCaptureFormat format_; | 110 media::VideoCaptureFormat format_; |
| 106 ::mojom::FacingMode facing_mode_; | 111 ::mojom::FacingMode facing_mode_; |
| 107 media::PowerLineFrequency power_line_frequency_; | 112 media::PowerLineFrequency power_line_frequency_; |
| 113 rtc::Optional<bool> noise_reduction_; |
| 108 }; | 114 }; |
| 109 | 115 |
| 110 VideoDeviceCaptureSourceSelectionResult ResultFromSettings( | 116 VideoDeviceCaptureSourceSelectionResult ResultFromSettings( |
| 111 const VideoDeviceCaptureSourceSettings& settings) { | 117 const VideoDeviceCaptureSourceSettings& settings) { |
| 112 VideoDeviceCaptureSourceSelectionResult result; | 118 VideoDeviceCaptureSourceSelectionResult result; |
| 113 result.capture_params.power_line_frequency = settings.power_line_frequency(); | 119 result.capture_params.power_line_frequency = settings.power_line_frequency(); |
| 114 result.capture_params.requested_format = settings.format(); | 120 result.capture_params.requested_format = settings.format(); |
| 115 result.device_id = settings.device_id(); | 121 result.device_id = settings.device_id(); |
| 116 result.facing_mode = settings.facing_mode(); | 122 result.facing_mode = settings.facing_mode(); |
| 123 result.noise_reduction = settings.noise_reduction(); |
| 117 result.failed_constraint_name = nullptr; | 124 result.failed_constraint_name = nullptr; |
| 118 | 125 |
| 119 return result; | 126 return result; |
| 120 } | 127 } |
| 121 | 128 |
| 122 // Generic distance function between two numeric values. Based on the fitness | 129 // Generic distance function between two numeric values. Based on the fitness |
| 123 // distance function described in | 130 // distance function described in |
| 124 // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance | 131 // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance |
| 125 double Distance(double value1, double value2) { | 132 double Distance(double value1, double value2) { |
| 126 if (std::fabs(value1 - value2) <= blink::DoubleConstraint::kConstraintEpsilon) | 133 if (std::fabs(value1 - value2) <= blink::DoubleConstraint::kConstraintEpsilon) |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 if ((constraint_has_max && source_value_long > constraint_max) || | 324 if ((constraint_has_max && source_value_long > constraint_max) || |
| 318 (constraint_has_min && source_value_long < constraint_min)) { | 325 (constraint_has_min && source_value_long < constraint_min)) { |
| 319 if (failed_constraint_name) | 326 if (failed_constraint_name) |
| 320 *failed_constraint_name = constraint.name(); | 327 *failed_constraint_name = constraint.name(); |
| 321 return HUGE_VAL; | 328 return HUGE_VAL; |
| 322 } | 329 } |
| 323 | 330 |
| 324 return 0.0; | 331 return 0.0; |
| 325 } | 332 } |
| 326 | 333 |
| 334 // Returns a custom distance function suitable for the googNoiseReduction |
| 335 // constraint, given a |constraint| and a candidate value |value|. |
| 336 // The distance is HUGE_VAL if |candidate_value| cannot satisfy |constraint|. |
| 337 // Otherwise, the distance is zero. |
| 338 double NoiseReductionConstraintSourceDistance( |
| 339 const blink::BooleanConstraint& constraint, |
| 340 const rtc::Optional<bool>& value, |
| 341 const char** failed_constraint_name) { |
| 342 if (!constraint.hasExact()) |
| 343 return 0.0; |
| 344 |
| 345 if (value && *value == constraint.exact()) |
| 346 return 0.0; |
| 347 |
| 348 if (failed_constraint_name) |
| 349 *failed_constraint_name = constraint.name(); |
| 350 return HUGE_VAL; |
| 351 } |
| 352 |
| 327 // Returns a custom distance for constraints that depend on the device | 353 // Returns a custom distance for constraints that depend on the device |
| 328 // characteristics that have a fixed value. | 354 // characteristics that have a fixed value. |
| 329 double DeviceSourceDistance( | 355 double DeviceSourceDistance( |
| 330 const std::string& device_id, | 356 const std::string& device_id, |
| 331 ::mojom::FacingMode facing_mode, | 357 ::mojom::FacingMode facing_mode, |
| 332 const blink::WebMediaTrackConstraintSet& constraint_set, | 358 const blink::WebMediaTrackConstraintSet& constraint_set, |
| 333 const char** failed_constraint_name) { | 359 const char** failed_constraint_name) { |
| 334 return StringConstraintSourceDistance(blink::WebString::fromASCII(device_id), | 360 return StringConstraintSourceDistance(blink::WebString::fromASCII(device_id), |
| 335 constraint_set.deviceId, | 361 constraint_set.deviceId, |
| 336 failed_constraint_name) + | 362 failed_constraint_name) + |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 double CandidateSourceDistance( | 398 double CandidateSourceDistance( |
| 373 const VideoDeviceCaptureSourceSettings& candidate, | 399 const VideoDeviceCaptureSourceSettings& candidate, |
| 374 const blink::WebMediaTrackConstraintSet& constraint_set, | 400 const blink::WebMediaTrackConstraintSet& constraint_set, |
| 375 const char** failed_constraint_name) { | 401 const char** failed_constraint_name) { |
| 376 return DeviceSourceDistance(candidate.device_id(), candidate.facing_mode(), | 402 return DeviceSourceDistance(candidate.device_id(), candidate.facing_mode(), |
| 377 constraint_set, failed_constraint_name) + | 403 constraint_set, failed_constraint_name) + |
| 378 FormatSourceDistance(candidate.format(), constraint_set, | 404 FormatSourceDistance(candidate.format(), constraint_set, |
| 379 failed_constraint_name) + | 405 failed_constraint_name) + |
| 380 PowerLineFrequencyConstraintSourceDistance( | 406 PowerLineFrequencyConstraintSourceDistance( |
| 381 constraint_set.googPowerLineFrequency, | 407 constraint_set.googPowerLineFrequency, |
| 382 candidate.power_line_frequency(), failed_constraint_name); | 408 candidate.power_line_frequency(), failed_constraint_name) + |
| 409 NoiseReductionConstraintSourceDistance( |
| 410 constraint_set.googNoiseReduction, candidate.noise_reduction(), |
| 411 failed_constraint_name); |
| 383 } | 412 } |
| 384 | 413 |
| 385 // Returns the fitness distance between |value| and |constraint|. | 414 // Returns the fitness distance between |value| and |constraint|. |
| 386 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. | 415 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. |
| 387 double StringConstraintFitnessDistance( | 416 double StringConstraintFitnessDistance( |
| 388 const blink::WebString& value, | 417 const blink::WebString& value, |
| 389 const blink::StringConstraint& constraint) { | 418 const blink::StringConstraint& constraint) { |
| 390 if (!constraint.hasIdeal()) | 419 if (!constraint.hasIdeal()) |
| 391 return 0.0; | 420 return 0.0; |
| 392 | 421 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 return 0.0; | 533 return 0.0; |
| 505 | 534 |
| 506 // This constraint is of type long, but it behaves as an enum. Thus, values | 535 // This constraint is of type long, but it behaves as an enum. Thus, values |
| 507 // equal to ideal have fitness 0.0 and any other values have fitness 1.0. | 536 // equal to ideal have fitness 0.0 and any other values have fitness 1.0. |
| 508 if (value == constraint.ideal()) | 537 if (value == constraint.ideal()) |
| 509 return 0.0; | 538 return 0.0; |
| 510 | 539 |
| 511 return 1.0; | 540 return 1.0; |
| 512 } | 541 } |
| 513 | 542 |
| 543 // Returns the fitness distance between |value| and |constraint| for the |
| 544 // googNoiseReduction constraint. |
| 545 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. |
| 546 double NoiseReductionConstraintFitnessDistance( |
| 547 const rtc::Optional<bool>& value, |
| 548 const blink::BooleanConstraint& constraint) { |
| 549 if (!constraint.hasIdeal()) |
| 550 return 0.0; |
| 551 |
| 552 if (value && value == constraint.ideal()) |
| 553 return 0.0; |
| 554 |
| 555 return 1.0; |
| 556 } |
| 557 |
| 514 // Returns the fitness distance between a settings candidate and a constraint | 558 // Returns the fitness distance between a settings candidate and a constraint |
| 515 // set. The returned value is the sum of the fitness distances between each | 559 // set. The returned value is the sum of the fitness distances between each |
| 516 // setting in |candidate| and the corresponding constraint in |constraint_set|. | 560 // setting in |candidate| and the corresponding constraint in |constraint_set|. |
| 517 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. | 561 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. |
| 518 double CandidateFitnessDistance( | 562 double CandidateFitnessDistance( |
| 519 const VideoDeviceCaptureSourceSettings& candidate, | 563 const VideoDeviceCaptureSourceSettings& candidate, |
| 520 const blink::WebMediaTrackConstraintSet& constraint_set) { | 564 const blink::WebMediaTrackConstraintSet& constraint_set) { |
| 521 DCHECK(std::isfinite( | 565 DCHECK(std::isfinite( |
| 522 CandidateSourceDistance(candidate, constraint_set, nullptr))); | 566 CandidateSourceDistance(candidate, constraint_set, nullptr))); |
| 523 double fitness = 0.0; | 567 double fitness = 0.0; |
| 524 fitness += AspectRatioConstraintFitnessDistance( | 568 fitness += AspectRatioConstraintFitnessDistance( |
| 525 candidate.GetHeight(), candidate.GetWidth(), constraint_set.height, | 569 candidate.GetHeight(), candidate.GetWidth(), constraint_set.height, |
| 526 constraint_set.width, constraint_set.aspectRatio); | 570 constraint_set.width, constraint_set.aspectRatio); |
| 527 fitness += StringConstraintFitnessDistance(candidate.GetDeviceId(), | 571 fitness += StringConstraintFitnessDistance(candidate.GetDeviceId(), |
| 528 constraint_set.deviceId); | 572 constraint_set.deviceId); |
| 529 fitness += StringConstraintFitnessDistance(candidate.GetFacingMode(), | 573 fitness += StringConstraintFitnessDistance(candidate.GetFacingMode(), |
| 530 constraint_set.facingMode); | 574 constraint_set.facingMode); |
| 531 fitness += FrameRateConstraintFitnessDistance(candidate.GetFrameRate(), | 575 fitness += FrameRateConstraintFitnessDistance(candidate.GetFrameRate(), |
| 532 constraint_set.frameRate); | 576 constraint_set.frameRate); |
| 533 fitness += StringConstraintFitnessDistance(candidate.GetVideoKind(), | 577 fitness += StringConstraintFitnessDistance(candidate.GetVideoKind(), |
| 534 constraint_set.videoKind); | 578 constraint_set.videoKind); |
| 535 fitness += PowerLineFrequencyConstraintFitnessDistance( | 579 fitness += PowerLineFrequencyConstraintFitnessDistance( |
| 536 candidate.GetPowerLineFrequency(), constraint_set.googPowerLineFrequency); | 580 candidate.GetPowerLineFrequency(), constraint_set.googPowerLineFrequency); |
| 581 fitness += NoiseReductionConstraintFitnessDistance( |
| 582 candidate.noise_reduction(), constraint_set.googNoiseReduction); |
| 537 fitness += ResolutionConstraintFitnessDistance(candidate.GetHeight(), | 583 fitness += ResolutionConstraintFitnessDistance(candidate.GetHeight(), |
| 538 constraint_set.height); | 584 constraint_set.height); |
| 539 fitness += ResolutionConstraintFitnessDistance(candidate.GetWidth(), | 585 fitness += ResolutionConstraintFitnessDistance(candidate.GetWidth(), |
| 540 constraint_set.width); | 586 constraint_set.width); |
| 541 | 587 |
| 542 return fitness; | 588 return fitness; |
| 543 } | 589 } |
| 544 | 590 |
| 545 // Returns the native fitness distance between a settings candidate and a | 591 // Returns the native fitness distance between a settings candidate and a |
| 546 // constraint set. The returned value is the sum of the fitness distances for | 592 // constraint set. The returned value is the sum of the fitness distances for |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 } | 630 } |
| 585 | 631 |
| 586 // Prefer default power-line frequency. | 632 // Prefer default power-line frequency. |
| 587 double power_line_frequency_distance = | 633 double power_line_frequency_distance = |
| 588 candidate.power_line_frequency() == | 634 candidate.power_line_frequency() == |
| 589 media::PowerLineFrequency::FREQUENCY_DEFAULT | 635 media::PowerLineFrequency::FREQUENCY_DEFAULT |
| 590 ? 0.0 | 636 ? 0.0 |
| 591 : HUGE_VAL; | 637 : HUGE_VAL; |
| 592 distance_vector->push_back(power_line_frequency_distance); | 638 distance_vector->push_back(power_line_frequency_distance); |
| 593 | 639 |
| 640 // Prefer not having a specific noise-reduction value and let the lower-layers |
| 641 // implementation choose a noise-reduction strategy. |
| 642 double noise_reduction_distance = |
| 643 candidate.noise_reduction() ? HUGE_VAL : 0.0; |
| 644 distance_vector->push_back(noise_reduction_distance); |
| 645 |
| 594 // Prefer a resolution with area close to the default. | 646 // Prefer a resolution with area close to the default. |
| 595 int candidate_area = candidate.format().frame_size.GetArea(); | 647 int candidate_area = candidate.format().frame_size.GetArea(); |
| 596 double resolution_distance = | 648 double resolution_distance = |
| 597 candidate_area == kDefaultResolutionArea | 649 candidate_area == kDefaultResolutionArea |
| 598 ? 0.0 | 650 ? 0.0 |
| 599 : Distance(candidate_area, kDefaultResolutionArea); | 651 : Distance(candidate_area, kDefaultResolutionArea); |
| 600 distance_vector->push_back(resolution_distance); | 652 distance_vector->push_back(resolution_distance); |
| 601 | 653 |
| 602 // Prefer a frame rate close to the default. | 654 // Prefer a frame rate close to the default. |
| 603 double frame_rate_distance = | 655 double frame_rate_distance = |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 continue; | 737 continue; |
| 686 | 738 |
| 687 for (auto& power_line_frequency : capabilities.power_line_capabilities) { | 739 for (auto& power_line_frequency : capabilities.power_line_capabilities) { |
| 688 double basic_power_line_frequency_distance = | 740 double basic_power_line_frequency_distance = |
| 689 PowerLineFrequencyConstraintSourceDistance( | 741 PowerLineFrequencyConstraintSourceDistance( |
| 690 constraints.basic().googPowerLineFrequency, | 742 constraints.basic().googPowerLineFrequency, |
| 691 power_line_frequency, &failed_constraint_name); | 743 power_line_frequency, &failed_constraint_name); |
| 692 if (!std::isfinite(basic_power_line_frequency_distance)) | 744 if (!std::isfinite(basic_power_line_frequency_distance)) |
| 693 continue; | 745 continue; |
| 694 | 746 |
| 695 // The candidate satisfies the basic constraint set. | 747 for (auto& noise_reduction : |
| 696 double candidate_basic_custom_distance = | 748 capabilities.noise_reduction_capabilities) { |
| 697 basic_device_distance + basic_format_distance + | 749 double basic_noise_reduction_distance = |
| 698 basic_power_line_frequency_distance; | 750 NoiseReductionConstraintSourceDistance( |
| 699 DCHECK(std::isfinite(candidate_basic_custom_distance)); | 751 constraints.basic().googNoiseReduction, noise_reduction, |
| 752 &failed_constraint_name); |
| 753 if (!std::isfinite(basic_noise_reduction_distance)) |
| 754 continue; |
| 700 | 755 |
| 701 // Temporary vector to save custom distances for advanced constraints. | 756 // The candidate satisfies the basic constraint set. |
| 702 // Custom distances must be added to the candidate distance vector after | 757 double candidate_basic_custom_distance = |
| 703 // all the spec-mandated values. | 758 basic_device_distance + basic_format_distance + |
| 704 DistanceVector advanced_custom_distance_vector; | 759 basic_power_line_frequency_distance + |
| 705 VideoDeviceCaptureSourceSettings candidate(device->device_id, format, | 760 basic_noise_reduction_distance; |
| 706 device->facing_mode, | 761 DCHECK(std::isfinite(candidate_basic_custom_distance)); |
| 707 power_line_frequency); | |
| 708 DistanceVector candidate_distance_vector; | |
| 709 // First criteria for valid candidates is satisfaction of advanced | |
| 710 // constraint sets. | |
| 711 for (const auto& advanced : constraints.advanced()) { | |
| 712 double custom_distance = | |
| 713 CandidateSourceDistance(candidate, advanced, nullptr); | |
| 714 advanced_custom_distance_vector.push_back(custom_distance); | |
| 715 double spec_distance = std::isfinite(custom_distance) ? 0 : 1; | |
| 716 candidate_distance_vector.push_back(spec_distance); | |
| 717 } | |
| 718 | 762 |
| 719 // Second criterion is fitness distance. | 763 // Temporary vector to save custom distances for advanced constraints. |
| 720 candidate_distance_vector.push_back( | 764 // Custom distances must be added to the candidate distance vector |
| 721 CandidateFitnessDistance(candidate, constraints.basic())); | 765 // after all the spec-mandated values. |
| 766 DistanceVector advanced_custom_distance_vector; |
| 767 VideoDeviceCaptureSourceSettings candidate( |
| 768 device->device_id, format, device->facing_mode, |
| 769 power_line_frequency, noise_reduction); |
| 770 DistanceVector candidate_distance_vector; |
| 771 // First criteria for valid candidates is satisfaction of advanced |
| 772 // constraint sets. |
| 773 for (const auto& advanced : constraints.advanced()) { |
| 774 double custom_distance = |
| 775 CandidateSourceDistance(candidate, advanced, nullptr); |
| 776 advanced_custom_distance_vector.push_back(custom_distance); |
| 777 double spec_distance = std::isfinite(custom_distance) ? 0 : 1; |
| 778 candidate_distance_vector.push_back(spec_distance); |
| 779 } |
| 722 | 780 |
| 723 // Third criteria are custom distances to constraint sets. | 781 // Second criterion is fitness distance. |
| 724 candidate_distance_vector.push_back(candidate_basic_custom_distance); | 782 candidate_distance_vector.push_back( |
| 725 std::copy(advanced_custom_distance_vector.begin(), | 783 CandidateFitnessDistance(candidate, constraints.basic())); |
| 726 advanced_custom_distance_vector.end(), | |
| 727 std::back_inserter(candidate_distance_vector)); | |
| 728 | 784 |
| 729 // Fourth criteria is native fitness distance. | 785 // Third criteria are custom distances to constraint sets. |
| 730 candidate_distance_vector.push_back( | 786 candidate_distance_vector.push_back(candidate_basic_custom_distance); |
| 731 CandidateNativeFitnessDistance(candidate, constraints.basic())); | 787 std::copy(advanced_custom_distance_vector.begin(), |
| 788 advanced_custom_distance_vector.end(), |
| 789 std::back_inserter(candidate_distance_vector)); |
| 732 | 790 |
| 733 // Final criteria are custom distances to default settings. | 791 // Fourth criteria is native fitness distance. |
| 734 AppendDistanceFromDefault(candidate, capabilities, | 792 candidate_distance_vector.push_back( |
| 735 &candidate_distance_vector); | 793 CandidateNativeFitnessDistance(candidate, constraints.basic())); |
| 736 | 794 |
| 737 DCHECK_EQ(best_distance.size(), candidate_distance_vector.size()); | 795 // Final criteria are custom distances to default settings. |
| 738 if (candidate_distance_vector < best_distance) { | 796 AppendDistanceFromDefault(candidate, capabilities, |
| 739 best_distance = candidate_distance_vector; | 797 &candidate_distance_vector); |
| 740 result = ResultFromSettings(candidate); | 798 |
| 799 DCHECK_EQ(best_distance.size(), candidate_distance_vector.size()); |
| 800 if (candidate_distance_vector < best_distance) { |
| 801 best_distance = candidate_distance_vector; |
| 802 result = ResultFromSettings(candidate); |
| 803 } |
| 741 } | 804 } |
| 742 } | 805 } |
| 743 } | 806 } |
| 744 } | 807 } |
| 745 | 808 |
| 746 if (!result.HasValue()) | 809 if (!result.HasValue()) |
| 747 result.failed_constraint_name = failed_constraint_name; | 810 result.failed_constraint_name = failed_constraint_name; |
| 748 | 811 |
| 749 return result; | 812 return result; |
| 750 } | 813 } |
| 751 | 814 |
| 752 } // namespace content | 815 } // namespace content |
| OLD | NEW |