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 |