| 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_audio.h" | 5 #include "content/renderer/media/media_stream_constraints_util_audio.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "content/common/media/media_stream_options.h" | 12 #include "content/common/media/media_stream_options.h" |
| 13 #include "content/renderer/media/media_stream_constraints_util_sets.h" | 13 #include "content/renderer/media/media_stream_constraints_util_sets.h" |
| 14 #include "content/renderer/media/media_stream_video_source.h" | 14 #include "content/renderer/media/media_stream_video_source.h" |
| 15 #include "media/base/limits.h" | 15 #include "media/base/limits.h" |
| 16 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" | 16 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" |
| 17 #include "third_party/WebKit/public/platform/WebString.h" | 17 #include "third_party/WebKit/public/platform/WebString.h" |
| 18 | 18 |
| 19 namespace content { | 19 namespace content { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 // This class has the same data as ::mojom::AudioInputDeviceCapabilities, but | 23 // This class has the same data as ::mojom::AudioInputDeviceCapabilities, but |
| 24 // adds extra operations to simplify the device-selection code. | 24 // adds extra operations to simplify access to device parameters. |
| 25 class AudioDeviceInfo { | 25 class AudioDeviceInfo { |
| 26 public: | 26 public: |
| 27 // This constructor is intended for device capture. | 27 // This constructor is intended for device capture. |
| 28 explicit AudioDeviceInfo( | 28 explicit AudioDeviceInfo( |
| 29 const ::mojom::AudioInputDeviceCapabilitiesPtr& device_info) | 29 const ::mojom::AudioInputDeviceCapabilitiesPtr& device_info) |
| 30 : device_id_(device_info->device_id), | 30 : device_id_(device_info->device_id), |
| 31 parameters_(device_info->parameters) { | 31 parameters_(device_info->parameters) { |
| 32 DCHECK(parameters_.IsValid()); | 32 DCHECK(parameters_.IsValid()); |
| 33 } | 33 } |
| 34 | 34 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 const char** failed_constraint_name) { | 76 const char** failed_constraint_name) { |
| 77 std::vector<AudioDeviceInfo> result; | 77 std::vector<AudioDeviceInfo> result; |
| 78 *failed_constraint_name = ""; | 78 *failed_constraint_name = ""; |
| 79 for (auto& device_capabilities : capabilities) { | 79 for (auto& device_capabilities : capabilities) { |
| 80 if (!constraint_set.device_id.Matches( | 80 if (!constraint_set.device_id.Matches( |
| 81 blink::WebString::FromASCII(device_capabilities->device_id))) { | 81 blink::WebString::FromASCII(device_capabilities->device_id))) { |
| 82 if (failed_constraint_name) | 82 if (failed_constraint_name) |
| 83 *failed_constraint_name = constraint_set.device_id.GetName(); | 83 *failed_constraint_name = constraint_set.device_id.GetName(); |
| 84 continue; | 84 continue; |
| 85 } | 85 } |
| 86 *failed_constraint_name = | |
| 87 IsOutsideConstraintRange(constraint_set.sample_rate, | |
| 88 device_capabilities->parameters.sample_rate()); | |
| 89 if (*failed_constraint_name) | |
| 90 continue; | |
| 91 | |
| 92 *failed_constraint_name = IsOutsideConstraintRange( | |
| 93 constraint_set.sample_size, | |
| 94 device_capabilities->parameters.bits_per_sample()); | |
| 95 if (*failed_constraint_name) | |
| 96 continue; | |
| 97 | |
| 98 *failed_constraint_name = | |
| 99 IsOutsideConstraintRange(constraint_set.channel_count, | |
| 100 device_capabilities->parameters.channels()); | |
| 101 if (*failed_constraint_name) | |
| 102 continue; | |
| 103 | |
| 104 result.push_back(AudioDeviceInfo(device_capabilities)); | 86 result.push_back(AudioDeviceInfo(device_capabilities)); |
| 105 } | 87 } |
| 106 | 88 |
| 107 if (!result.empty()) | 89 if (!result.empty()) |
| 108 *failed_constraint_name = nullptr; | 90 *failed_constraint_name = nullptr; |
| 109 | 91 |
| 110 return AudioDeviceSet(result); | 92 return AudioDeviceSet(std::move(result)); |
| 111 } | 93 } |
| 112 | 94 |
| 113 AudioDeviceSet AudioDeviceSetForContentCapture( | 95 AudioDeviceSet AudioDeviceSetForContentCapture( |
| 114 const blink::WebMediaTrackConstraintSet& constraint_set, | 96 const blink::WebMediaTrackConstraintSet& constraint_set, |
| 115 const char** failed_constraint_name = nullptr) { | 97 const char** failed_constraint_name = nullptr) { |
| 116 if (!constraint_set.device_id.HasExact()) | 98 if (!constraint_set.device_id.HasExact()) |
| 117 return AudioDeviceSet::UniversalSet(); | 99 return AudioDeviceSet::UniversalSet(); |
| 118 | 100 |
| 119 std::vector<AudioDeviceInfo> result; | 101 std::vector<AudioDeviceInfo> result; |
| 120 for (auto& device_id : constraint_set.device_id.Exact()) | 102 for (auto& device_id : constraint_set.device_id.Exact()) |
| 121 result.push_back(AudioDeviceInfo(device_id.Utf8())); | 103 result.push_back(AudioDeviceInfo(device_id.Utf8())); |
| 122 | 104 |
| 123 return AudioDeviceSet(result); | 105 return AudioDeviceSet(std::move(result)); |
| 124 } | 106 } |
| 125 | 107 |
| 126 // This class represents a set of possible candidate settings. | 108 // This class represents a set of possible candidate settings. |
| 127 // The SelectSettings algorithm starts with a set containing all possible | 109 // The SelectSettings algorithm starts with a set containing all possible |
| 128 // candidates based on hardware capabilities and/or allowed values for supported | 110 // candidates based on hardware capabilities and/or allowed values for supported |
| 129 // properties. The is then reduced progressively as the basic and advanced | 111 // properties. The is then reduced progressively as the basic and advanced |
| 130 // constraint sets are applied. | 112 // constraint sets are applied. |
| 131 // In the end, if the set of candidates is empty, SelectSettings fails. | 113 // In the end, if the set of candidates is empty, SelectSettings fails. |
| 132 // If not, the ideal values (if any) or tie breaker rules are used to select | 114 // If not, the ideal values (if any) or tie breaker rules are used to select |
| 133 // the final settings based on the candidates that survived the application | 115 // the final settings based on the candidates that survived the application |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 bool_sets_[GOOG_ECHO_CANCELLATION]); | 295 bool_sets_[GOOG_ECHO_CANCELLATION]); |
| 314 // echoCancellation and googEchoCancellation constraints should not | 296 // echoCancellation and googEchoCancellation constraints should not |
| 315 // contradict each other. Mark the set as empty if they do. | 297 // contradict each other. Mark the set as empty if they do. |
| 316 if (echo_cancellation_intersection.IsEmpty()) { | 298 if (echo_cancellation_intersection.IsEmpty()) { |
| 317 failed_constraint_name_ = | 299 failed_constraint_name_ = |
| 318 blink::WebMediaTrackConstraintSet().echo_cancellation.GetName(); | 300 blink::WebMediaTrackConstraintSet().echo_cancellation.GetName(); |
| 319 } | 301 } |
| 320 } | 302 } |
| 321 | 303 |
| 322 // Fitness function for constraints involved in device selection. | 304 // Fitness function for constraints involved in device selection. |
| 323 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance | 305 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance |
| 306 // TODO(guidou): Add support for sampleRate, sampleSize and channelCount |
| 307 // constraints. http://crbug.com/ |
| 324 double DeviceInfoFitness( | 308 double DeviceInfoFitness( |
| 325 bool is_device_capture, | 309 bool is_device_capture, |
| 326 const AudioDeviceInfo& device_info, | 310 const AudioDeviceInfo& device_info, |
| 327 const blink::WebMediaTrackConstraintSet& basic_constraint_set) { | 311 const blink::WebMediaTrackConstraintSet& basic_constraint_set) { |
| 328 double fitness = 0.0; | 312 return StringConstraintFitnessDistance( |
| 329 fitness += StringConstraintFitnessDistance( | |
| 330 blink::WebString::FromASCII(device_info.device_id()), | 313 blink::WebString::FromASCII(device_info.device_id()), |
| 331 basic_constraint_set.device_id); | 314 basic_constraint_set.device_id); |
| 332 | |
| 333 if (!is_device_capture) | |
| 334 return fitness; | |
| 335 | |
| 336 if (basic_constraint_set.sample_rate.HasIdeal()) { | |
| 337 fitness += NumericConstraintFitnessDistance( | |
| 338 device_info.SampleRate(), basic_constraint_set.sample_rate.Ideal()); | |
| 339 } | |
| 340 | |
| 341 if (basic_constraint_set.sample_size.HasIdeal()) { | |
| 342 fitness += NumericConstraintFitnessDistance( | |
| 343 device_info.SampleSize(), basic_constraint_set.sample_size.Ideal()); | |
| 344 } | |
| 345 | |
| 346 if (basic_constraint_set.channel_count.HasIdeal()) { | |
| 347 fitness += NumericConstraintFitnessDistance( | |
| 348 device_info.ChannelCount(), basic_constraint_set.channel_count.Ideal()); | |
| 349 } | |
| 350 | |
| 351 return fitness; | |
| 352 } | 315 } |
| 353 | 316 |
| 354 AudioDeviceInfo SelectDevice( | 317 AudioDeviceInfo SelectDevice( |
| 355 const AudioDeviceSet& audio_device_set, | 318 const AudioDeviceSet& audio_device_set, |
| 356 const blink::WebMediaTrackConstraintSet& basic_constraint_set, | 319 const blink::WebMediaTrackConstraintSet& basic_constraint_set, |
| 357 const std::string& default_device_id, | 320 const std::string& default_device_id, |
| 358 bool is_device_capture) { | 321 bool is_device_capture) { |
| 359 DCHECK(!audio_device_set.IsEmpty()); | 322 DCHECK(!audio_device_set.IsEmpty()); |
| 360 if (audio_device_set.is_universal()) { | 323 if (audio_device_set.is_universal()) { |
| 361 DCHECK(!is_device_capture); | 324 DCHECK(!is_device_capture); |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 | 568 |
| 606 std::string default_device_id; | 569 std::string default_device_id; |
| 607 if (!capabilities.empty()) | 570 if (!capabilities.empty()) |
| 608 default_device_id = (*capabilities.begin())->device_id; | 571 default_device_id = (*capabilities.begin())->device_id; |
| 609 | 572 |
| 610 return SelectResult(candidates, constraints.Basic(), default_device_id, | 573 return SelectResult(candidates, constraints.Basic(), default_device_id, |
| 611 media_stream_source); | 574 media_stream_source); |
| 612 } | 575 } |
| 613 | 576 |
| 614 } // namespace content | 577 } // namespace content |
| OLD | NEW |