| Index: content/renderer/media/media_stream_constraints_util_video_device.cc
|
| diff --git a/content/renderer/media/media_stream_constraints_util_video_device.cc b/content/renderer/media/media_stream_constraints_util_video_device.cc
|
| index 3e2f3e8032cd97cb28c41c144263b2d56ca46db6..84d415f58de120bdbc4d0f0653a7c47d30eca990 100644
|
| --- a/content/renderer/media/media_stream_constraints_util_video_device.cc
|
| +++ b/content/renderer/media/media_stream_constraints_util_video_device.cc
|
| @@ -21,8 +21,8 @@ namespace {
|
|
|
| // Number of default settings to be used as final tie-breaking criteria for
|
| // settings that are equally good at satisfying constraints:
|
| -// device ID, power-line frequency, resolution and frame rate.
|
| -const int kNumDefaultDistanceEntries = 4;
|
| +// device ID, power-line frequency, noise reduction, resolution and frame rate.
|
| +const int kNumDefaultDistanceEntries = 5;
|
|
|
| // The default resolution to be preferred as tie-breaking criterion.
|
| const int kDefaultResolutionArea = MediaStreamVideoSource::kDefaultWidth *
|
| @@ -60,11 +60,13 @@ struct VideoDeviceCaptureSourceSettings {
|
| const std::string& device_id,
|
| const media::VideoCaptureFormat& format,
|
| ::mojom::FacingMode facing_mode,
|
| - media::PowerLineFrequency power_line_frequency)
|
| + media::PowerLineFrequency power_line_frequency,
|
| + const rtc::Optional<bool>& noise_reduction)
|
| : device_id_(device_id),
|
| format_(format),
|
| facing_mode_(facing_mode),
|
| - power_line_frequency_(power_line_frequency) {}
|
| + power_line_frequency_(power_line_frequency),
|
| + noise_reduction_(noise_reduction) {}
|
|
|
| VideoDeviceCaptureSourceSettings(
|
| const VideoDeviceCaptureSourceSettings& other) = default;
|
| @@ -99,12 +101,16 @@ struct VideoDeviceCaptureSourceSettings {
|
| media::PowerLineFrequency power_line_frequency() const {
|
| return power_line_frequency_;
|
| }
|
| + const rtc::Optional<bool>& noise_reduction() const {
|
| + return noise_reduction_;
|
| + }
|
|
|
| private:
|
| std::string device_id_;
|
| media::VideoCaptureFormat format_;
|
| ::mojom::FacingMode facing_mode_;
|
| media::PowerLineFrequency power_line_frequency_;
|
| + rtc::Optional<bool> noise_reduction_;
|
| };
|
|
|
| VideoDeviceCaptureSourceSelectionResult ResultFromSettings(
|
| @@ -114,6 +120,7 @@ VideoDeviceCaptureSourceSelectionResult ResultFromSettings(
|
| result.capture_params.requested_format = settings.format();
|
| result.device_id = settings.device_id();
|
| result.facing_mode = settings.facing_mode();
|
| + result.noise_reduction = settings.noise_reduction();
|
| result.failed_constraint_name = nullptr;
|
|
|
| return result;
|
| @@ -324,6 +331,25 @@ double PowerLineFrequencyConstraintSourceDistance(
|
| return 0.0;
|
| }
|
|
|
| +// Returns a custom distance function suitable for the googNoiseReduction
|
| +// constraint, given a |constraint| and a candidate value |value|.
|
| +// The distance is HUGE_VAL if |candidate_value| cannot satisfy |constraint|.
|
| +// Otherwise, the distance is zero.
|
| +double NoiseReductionConstraintSourceDistance(
|
| + const blink::BooleanConstraint& constraint,
|
| + const rtc::Optional<bool>& value,
|
| + const char** failed_constraint_name) {
|
| + if (!constraint.hasExact())
|
| + return 0.0;
|
| +
|
| + if (value && *value == constraint.exact())
|
| + return 0.0;
|
| +
|
| + if (failed_constraint_name)
|
| + *failed_constraint_name = constraint.name();
|
| + return HUGE_VAL;
|
| +}
|
| +
|
| // Returns a custom distance for constraints that depend on the device
|
| // characteristics that have a fixed value.
|
| double DeviceSourceDistance(
|
| @@ -379,7 +405,10 @@ double CandidateSourceDistance(
|
| failed_constraint_name) +
|
| PowerLineFrequencyConstraintSourceDistance(
|
| constraint_set.googPowerLineFrequency,
|
| - candidate.power_line_frequency(), failed_constraint_name);
|
| + candidate.power_line_frequency(), failed_constraint_name) +
|
| + NoiseReductionConstraintSourceDistance(
|
| + constraint_set.googNoiseReduction, candidate.noise_reduction(),
|
| + failed_constraint_name);
|
| }
|
|
|
| // Returns the fitness distance between |value| and |constraint|.
|
| @@ -511,6 +540,21 @@ double PowerLineFrequencyConstraintFitnessDistance(
|
| return 1.0;
|
| }
|
|
|
| +// Returns the fitness distance between |value| and |constraint| for the
|
| +// googNoiseReduction constraint.
|
| +// Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
|
| +double NoiseReductionConstraintFitnessDistance(
|
| + const rtc::Optional<bool>& value,
|
| + const blink::BooleanConstraint& constraint) {
|
| + if (!constraint.hasIdeal())
|
| + return 0.0;
|
| +
|
| + if (value && value == constraint.ideal())
|
| + return 0.0;
|
| +
|
| + return 1.0;
|
| +}
|
| +
|
| // Returns the fitness distance between a settings candidate and a constraint
|
| // set. The returned value is the sum of the fitness distances between each
|
| // setting in |candidate| and the corresponding constraint in |constraint_set|.
|
| @@ -534,6 +578,8 @@ double CandidateFitnessDistance(
|
| constraint_set.videoKind);
|
| fitness += PowerLineFrequencyConstraintFitnessDistance(
|
| candidate.GetPowerLineFrequency(), constraint_set.googPowerLineFrequency);
|
| + fitness += NoiseReductionConstraintFitnessDistance(
|
| + candidate.noise_reduction(), constraint_set.googNoiseReduction);
|
| fitness += ResolutionConstraintFitnessDistance(candidate.GetHeight(),
|
| constraint_set.height);
|
| fitness += ResolutionConstraintFitnessDistance(candidate.GetWidth(),
|
| @@ -591,6 +637,12 @@ void AppendDistanceFromDefault(
|
| : HUGE_VAL;
|
| distance_vector->push_back(power_line_frequency_distance);
|
|
|
| + // Prefer not having a specific noise-reduction value and let the lower-layers
|
| + // implementation choose a noise-reduction strategy.
|
| + double noise_reduction_distance =
|
| + candidate.noise_reduction() ? HUGE_VAL : 0.0;
|
| + distance_vector->push_back(noise_reduction_distance);
|
| +
|
| // Prefer a resolution with area close to the default.
|
| int candidate_area = candidate.format().frame_size.GetArea();
|
| double resolution_distance =
|
| @@ -692,52 +744,63 @@ VideoDeviceCaptureSourceSelectionResult SelectVideoDeviceCaptureSourceSettings(
|
| if (!std::isfinite(basic_power_line_frequency_distance))
|
| continue;
|
|
|
| - // The candidate satisfies the basic constraint set.
|
| - double candidate_basic_custom_distance =
|
| - basic_device_distance + basic_format_distance +
|
| - basic_power_line_frequency_distance;
|
| - DCHECK(std::isfinite(candidate_basic_custom_distance));
|
| -
|
| - // Temporary vector to save custom distances for advanced constraints.
|
| - // Custom distances must be added to the candidate distance vector after
|
| - // all the spec-mandated values.
|
| - DistanceVector advanced_custom_distance_vector;
|
| - VideoDeviceCaptureSourceSettings candidate(device->device_id, format,
|
| - device->facing_mode,
|
| - power_line_frequency);
|
| - DistanceVector candidate_distance_vector;
|
| - // First criteria for valid candidates is satisfaction of advanced
|
| - // constraint sets.
|
| - for (const auto& advanced : constraints.advanced()) {
|
| - double custom_distance =
|
| - CandidateSourceDistance(candidate, advanced, nullptr);
|
| - advanced_custom_distance_vector.push_back(custom_distance);
|
| - double spec_distance = std::isfinite(custom_distance) ? 0 : 1;
|
| - candidate_distance_vector.push_back(spec_distance);
|
| - }
|
| -
|
| - // Second criterion is fitness distance.
|
| - candidate_distance_vector.push_back(
|
| - CandidateFitnessDistance(candidate, constraints.basic()));
|
| -
|
| - // Third criteria are custom distances to constraint sets.
|
| - candidate_distance_vector.push_back(candidate_basic_custom_distance);
|
| - std::copy(advanced_custom_distance_vector.begin(),
|
| - advanced_custom_distance_vector.end(),
|
| - std::back_inserter(candidate_distance_vector));
|
| -
|
| - // Fourth criteria is native fitness distance.
|
| - candidate_distance_vector.push_back(
|
| - CandidateNativeFitnessDistance(candidate, constraints.basic()));
|
| -
|
| - // Final criteria are custom distances to default settings.
|
| - AppendDistanceFromDefault(candidate, capabilities,
|
| - &candidate_distance_vector);
|
| -
|
| - DCHECK_EQ(best_distance.size(), candidate_distance_vector.size());
|
| - if (candidate_distance_vector < best_distance) {
|
| - best_distance = candidate_distance_vector;
|
| - result = ResultFromSettings(candidate);
|
| + for (auto& noise_reduction :
|
| + capabilities.noise_reduction_capabilities) {
|
| + double basic_noise_reduction_distance =
|
| + NoiseReductionConstraintSourceDistance(
|
| + constraints.basic().googNoiseReduction, noise_reduction,
|
| + &failed_constraint_name);
|
| + if (!std::isfinite(basic_noise_reduction_distance))
|
| + continue;
|
| +
|
| + // The candidate satisfies the basic constraint set.
|
| + double candidate_basic_custom_distance =
|
| + basic_device_distance + basic_format_distance +
|
| + basic_power_line_frequency_distance +
|
| + basic_noise_reduction_distance;
|
| + DCHECK(std::isfinite(candidate_basic_custom_distance));
|
| +
|
| + // Temporary vector to save custom distances for advanced constraints.
|
| + // Custom distances must be added to the candidate distance vector
|
| + // after all the spec-mandated values.
|
| + DistanceVector advanced_custom_distance_vector;
|
| + VideoDeviceCaptureSourceSettings candidate(
|
| + device->device_id, format, device->facing_mode,
|
| + power_line_frequency, noise_reduction);
|
| + DistanceVector candidate_distance_vector;
|
| + // First criteria for valid candidates is satisfaction of advanced
|
| + // constraint sets.
|
| + for (const auto& advanced : constraints.advanced()) {
|
| + double custom_distance =
|
| + CandidateSourceDistance(candidate, advanced, nullptr);
|
| + advanced_custom_distance_vector.push_back(custom_distance);
|
| + double spec_distance = std::isfinite(custom_distance) ? 0 : 1;
|
| + candidate_distance_vector.push_back(spec_distance);
|
| + }
|
| +
|
| + // Second criterion is fitness distance.
|
| + candidate_distance_vector.push_back(
|
| + CandidateFitnessDistance(candidate, constraints.basic()));
|
| +
|
| + // Third criteria are custom distances to constraint sets.
|
| + candidate_distance_vector.push_back(candidate_basic_custom_distance);
|
| + std::copy(advanced_custom_distance_vector.begin(),
|
| + advanced_custom_distance_vector.end(),
|
| + std::back_inserter(candidate_distance_vector));
|
| +
|
| + // Fourth criteria is native fitness distance.
|
| + candidate_distance_vector.push_back(
|
| + CandidateNativeFitnessDistance(candidate, constraints.basic()));
|
| +
|
| + // Final criteria are custom distances to default settings.
|
| + AppendDistanceFromDefault(candidate, capabilities,
|
| + &candidate_distance_vector);
|
| +
|
| + DCHECK_EQ(best_distance.size(), candidate_distance_vector.size());
|
| + if (candidate_distance_vector < best_distance) {
|
| + best_distance = candidate_distance_vector;
|
| + result = ResultFromSettings(candidate);
|
| + }
|
| }
|
| }
|
| }
|
|
|