OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/user_media_client_impl.h" | 5 #include "content/renderer/media/user_media_client_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
17 #include "base/task_runner.h" | 17 #include "base/task_runner.h" |
18 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
20 #include "content/public/renderer/render_frame.h" | 20 #include "content/public/renderer/render_frame.h" |
21 #include "content/renderer/media/local_media_stream_audio_source.h" | 21 #include "content/renderer/media/local_media_stream_audio_source.h" |
22 #include "content/renderer/media/media_stream.h" | 22 #include "content/renderer/media/media_stream.h" |
23 #include "content/renderer/media/media_stream_constraints_util.h" | 23 #include "content/renderer/media/media_stream_constraints_util.h" |
24 #include "content/renderer/media/media_stream_constraints_util_audio.h" | |
24 #include "content/renderer/media/media_stream_constraints_util_video_content.h" | 25 #include "content/renderer/media/media_stream_constraints_util_video_content.h" |
25 #include "content/renderer/media/media_stream_constraints_util_video_device.h" | 26 #include "content/renderer/media/media_stream_constraints_util_video_device.h" |
26 #include "content/renderer/media/media_stream_dispatcher.h" | 27 #include "content/renderer/media/media_stream_dispatcher.h" |
27 #include "content/renderer/media/media_stream_video_capturer_source.h" | 28 #include "content/renderer/media/media_stream_video_capturer_source.h" |
28 #include "content/renderer/media/media_stream_video_track.h" | 29 #include "content/renderer/media/media_stream_video_track.h" |
29 #include "content/renderer/media/peer_connection_tracker.h" | 30 #include "content/renderer/media/peer_connection_tracker.h" |
30 #include "content/renderer/media/webrtc/processed_local_audio_source.h" | 31 #include "content/renderer/media/webrtc/processed_local_audio_source.h" |
31 #include "content/renderer/media/webrtc_logging.h" | 32 #include "content/renderer/media/webrtc_logging.h" |
32 #include "content/renderer/media/webrtc_uma_histograms.h" | 33 #include "content/renderer/media/webrtc_uma_histograms.h" |
33 #include "content/renderer/render_thread_impl.h" | 34 #include "content/renderer/render_thread_impl.h" |
34 #include "media/capture/video_capture_types.h" | 35 #include "media/capture/video_capture_types.h" |
35 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" | 36 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" |
36 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" | 37 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" |
37 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 38 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
38 #include "third_party/WebKit/public/platform/WebString.h" | 39 #include "third_party/WebKit/public/platform/WebString.h" |
39 #include "third_party/WebKit/public/web/WebDocument.h" | 40 #include "third_party/WebKit/public/web/WebDocument.h" |
40 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 41 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
41 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | 42 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
42 | 43 |
43 namespace content { | 44 namespace content { |
44 namespace { | 45 namespace { |
45 | 46 |
46 void CopyFirstString(const blink::StringConstraint& constraint, | 47 void CopyFirstString(const blink::StringConstraint& constraint, |
47 std::string* destination) { | 48 std::string* destination) { |
48 if (!constraint.Exact().IsEmpty()) | 49 if (!constraint.Exact().IsEmpty()) |
49 *destination = constraint.Exact()[0].Utf8(); | 50 *destination = constraint.Exact()[0].Utf8(); |
50 } | 51 } |
51 | 52 |
53 // TODO(guidou): Remove this function. http://crbug.com/706408 | |
52 bool FindDeviceId(const blink::WebVector<blink::WebString> candidates, | 54 bool FindDeviceId(const blink::WebVector<blink::WebString> candidates, |
53 const MediaDeviceInfoArray& device_infos, | 55 const MediaDeviceInfoArray& device_infos, |
54 std::string* device_id) { | 56 std::string* device_id) { |
55 for (const auto& candidate : candidates) { | 57 for (const auto& candidate : candidates) { |
56 auto it = std::find_if(device_infos.begin(), device_infos.end(), | 58 auto it = std::find_if(device_infos.begin(), device_infos.end(), |
57 [&candidate](const MediaDeviceInfo& info) { | 59 [&candidate](const MediaDeviceInfo& info) { |
58 return info.device_id == candidate.Utf8(); | 60 return info.device_id == candidate.Utf8(); |
59 }); | 61 }); |
60 | 62 |
61 if (it != device_infos.end()) { | 63 if (it != device_infos.end()) { |
(...skipping 10 matching lines...) Expand all Loading... | |
72 // false. If such a device is not found in |device_infos|, the function returns | 74 // false. If such a device is not found in |device_infos|, the function returns |
73 // false and |*device_id| is left unmodified. | 75 // false and |*device_id| is left unmodified. |
74 // If more than one device ID is requested as an exact basic constraint in | 76 // If more than one device ID is requested as an exact basic constraint in |
75 // |constraint|, the function returns false and |*device_id| is left unmodified. | 77 // |constraint|, the function returns false and |*device_id| is left unmodified. |
76 // If no device ID is requested as an exact basic constraint, and at least one | 78 // If no device ID is requested as an exact basic constraint, and at least one |
77 // device ID requested as an ideal basic constraint or as an exact or ideal | 79 // device ID requested as an ideal basic constraint or as an exact or ideal |
78 // advanced constraint in |constraints| is found in |device_infos|, the first | 80 // advanced constraint in |constraints| is found in |device_infos|, the first |
79 // such device ID is copied to |*device_id| and the function returns true. | 81 // such device ID is copied to |*device_id| and the function returns true. |
80 // If no such device ID is found, |*device_id| is left unmodified and the | 82 // If no such device ID is found, |*device_id| is left unmodified and the |
81 // function returns true. | 83 // function returns true. |
82 // TODO(guidou): Replace with a spec-compliant selection algorithm. See | 84 // TODO(guidou): Remove this function. http://crbug.com/706408 |
83 // http://crbug.com/657733. | |
84 bool PickDeviceId(const blink::WebMediaConstraints& constraints, | 85 bool PickDeviceId(const blink::WebMediaConstraints& constraints, |
85 const MediaDeviceInfoArray& device_infos, | 86 const MediaDeviceInfoArray& device_infos, |
86 std::string* device_id) { | 87 std::string* device_id) { |
87 DCHECK(!constraints.IsNull()); | 88 DCHECK(!constraints.IsNull()); |
88 DCHECK(device_id->empty()); | 89 DCHECK(device_id->empty()); |
89 | 90 |
90 if (constraints.Basic().device_id.Exact().size() > 1) { | 91 if (constraints.Basic().device_id.Exact().size() > 1) { |
91 LOG(ERROR) << "Only one required device ID is supported"; | 92 LOG(ERROR) << "Only one required device ID is supported"; |
92 return false; | 93 return false; |
93 } | 94 } |
(...skipping 22 matching lines...) Expand all Loading... | |
116 } | 117 } |
117 | 118 |
118 // No valid alternate device ID found. Select default device. | 119 // No valid alternate device ID found. Select default device. |
119 return true; | 120 return true; |
120 } | 121 } |
121 | 122 |
122 bool IsDeviceSource(const std::string& source) { | 123 bool IsDeviceSource(const std::string& source) { |
123 return source.empty(); | 124 return source.empty(); |
124 } | 125 } |
125 | 126 |
126 // TODO(guidou): Remove once audio constraints are processed with spec-compliant | 127 // TODO(guidou): Remove this function. http://crbug.com/706408 |
127 // algorithm. See http://crbug.com/657733. | |
128 void CopyConstraintsToTrackControls( | 128 void CopyConstraintsToTrackControls( |
129 const blink::WebMediaConstraints& constraints, | 129 const blink::WebMediaConstraints& constraints, |
130 TrackControls* track_controls, | 130 TrackControls* track_controls, |
131 bool* request_devices) { | 131 bool* request_devices) { |
132 DCHECK(!constraints.IsNull()); | 132 DCHECK(!constraints.IsNull()); |
133 track_controls->requested = true; | 133 track_controls->requested = true; |
134 CopyFirstString(constraints.Basic().media_stream_source, | 134 CopyFirstString(constraints.Basic().media_stream_source, |
135 &track_controls->stream_source); | 135 &track_controls->stream_source); |
136 if (IsDeviceSource(track_controls->stream_source)) { | 136 if (IsDeviceSource(track_controls->stream_source)) { |
137 bool request_devices_advanced = false; | 137 bool request_devices_advanced = false; |
(...skipping 12 matching lines...) Expand all Loading... | |
150 } | 150 } |
151 | 151 |
152 void InitializeTrackControls(const blink::WebMediaConstraints& constraints, | 152 void InitializeTrackControls(const blink::WebMediaConstraints& constraints, |
153 TrackControls* track_controls) { | 153 TrackControls* track_controls) { |
154 DCHECK(!constraints.IsNull()); | 154 DCHECK(!constraints.IsNull()); |
155 track_controls->requested = true; | 155 track_controls->requested = true; |
156 CopyFirstString(constraints.Basic().media_stream_source, | 156 CopyFirstString(constraints.Basic().media_stream_source, |
157 &track_controls->stream_source); | 157 &track_controls->stream_source); |
158 } | 158 } |
159 | 159 |
160 // TODO(guidou): Remove this function. http://crbug.com/706408 | |
160 void CopyHotwordAndLocalEchoToStreamControls( | 161 void CopyHotwordAndLocalEchoToStreamControls( |
161 const blink::WebMediaConstraints& audio_constraints, | 162 const blink::WebMediaConstraints& audio_constraints, |
162 StreamControls* controls) { | 163 StreamControls* controls) { |
163 if (audio_constraints.IsNull()) | 164 if (audio_constraints.IsNull()) |
164 return; | 165 return; |
165 | 166 |
166 if (audio_constraints.Basic().hotword_enabled.HasExact()) { | 167 if (audio_constraints.Basic().hotword_enabled.HasExact()) { |
167 controls->hotword_enabled = | 168 controls->hotword_enabled = |
168 audio_constraints.Basic().hotword_enabled.Exact(); | 169 audio_constraints.Basic().hotword_enabled.Exact(); |
169 } else { | 170 } else { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 case MEDIA_DEVICE_TYPE_VIDEO_INPUT: | 213 case MEDIA_DEVICE_TYPE_VIDEO_INPUT: |
213 return blink::WebMediaDeviceInfo::kMediaDeviceKindVideoInput; | 214 return blink::WebMediaDeviceInfo::kMediaDeviceKindVideoInput; |
214 case MEDIA_DEVICE_TYPE_AUDIO_OUTPUT: | 215 case MEDIA_DEVICE_TYPE_AUDIO_OUTPUT: |
215 return blink::WebMediaDeviceInfo::kMediaDeviceKindAudioOutput; | 216 return blink::WebMediaDeviceInfo::kMediaDeviceKindAudioOutput; |
216 default: | 217 default: |
217 NOTREACHED(); | 218 NOTREACHED(); |
218 return blink::WebMediaDeviceInfo::kMediaDeviceKindAudioInput; | 219 return blink::WebMediaDeviceInfo::kMediaDeviceKindAudioInput; |
219 } | 220 } |
220 } | 221 } |
221 | 222 |
223 bool IsValidAudioContentSource(const std::string& source) { | |
224 return source == kMediaStreamSourceTab || | |
225 source == kMediaStreamSourceDesktop || | |
226 source == kMediaStreamSourceSystem; | |
227 } | |
228 | |
229 bool IsValidVideoContentSource(const std::string& source) { | |
230 return source == kMediaStreamSourceTab || | |
231 source == kMediaStreamSourceDesktop || | |
232 source == kMediaStreamSourceScreen; | |
233 } | |
234 | |
222 static int g_next_request_id = 0; | 235 static int g_next_request_id = 0; |
223 | 236 |
224 } // namespace | 237 } // namespace |
225 | 238 |
226 // Class for storing information about a Blink request to create a | 239 // Class for storing information about a Blink request to create a |
227 // MediaStream. | 240 // MediaStream. |
228 class UserMediaClientImpl::UserMediaRequestInfo | 241 class UserMediaClientImpl::UserMediaRequestInfo |
229 : public base::SupportsWeakPtr<UserMediaRequestInfo> { | 242 : public base::SupportsWeakPtr<UserMediaRequestInfo> { |
230 public: | 243 public: |
231 using ResourcesReady = | 244 using ResourcesReady = |
(...skipping 26 matching lines...) Expand all Loading... | |
258 // Called when a local audio source has finished (or failed) initializing. | 271 // Called when a local audio source has finished (or failed) initializing. |
259 void OnAudioSourceStarted(MediaStreamSource* source, | 272 void OnAudioSourceStarted(MediaStreamSource* source, |
260 MediaStreamRequestResult result, | 273 MediaStreamRequestResult result, |
261 const blink::WebString& result_name); | 274 const blink::WebString& result_name); |
262 | 275 |
263 int request_id() const { return request_id_; } | 276 int request_id() const { return request_id_; } |
264 | 277 |
265 State state() const { return state_; } | 278 State state() const { return state_; } |
266 void set_state(State state) { state_ = state; } | 279 void set_state(State state) { state_ = state; } |
267 | 280 |
268 bool enable_automatic_output_device_selection() const { | 281 // TODO(guidou): Remove this function. http://crbug.com/706408 |
269 return enable_automatic_output_device_selection_; | 282 bool legacy_enable_automatic_output_device_selection() const { |
283 DCHECK(IsOldAudioConstraints()); | |
284 return legacy_enable_automatic_output_device_selection_; | |
270 } | 285 } |
271 void set_enable_automatic_output_device_selection(bool value) { | 286 // TODO(guidou): Remove this function. http://crbug.com/706408 |
272 enable_automatic_output_device_selection_ = value; | 287 void set_legacy_enable_automatic_output_device_selection(bool value) { |
288 DCHECK(IsOldAudioConstraints()); | |
289 legacy_enable_automatic_output_device_selection_ = value; | |
290 } | |
291 const AudioCaptureSettings& audio_capture_settings() const { | |
292 DCHECK(!IsOldAudioConstraints()); | |
293 return audio_capture_settings_; | |
294 } | |
295 bool is_audio_content_capture() const { | |
296 DCHECK(!IsOldAudioConstraints()); | |
297 return audio_capture_settings_.HasValue() && is_audio_content_capture_; | |
298 } | |
299 bool is_audio_device_capture() const { | |
300 DCHECK(!IsOldAudioConstraints()); | |
301 return audio_capture_settings_.HasValue() && !is_audio_content_capture_; | |
302 } | |
303 void SetAudioCaptureSettings(const AudioCaptureSettings& settings, | |
304 bool is_content_capture) { | |
305 DCHECK(settings.HasValue()); | |
306 is_audio_content_capture_ = is_content_capture; | |
307 audio_capture_settings_ = settings; | |
273 } | 308 } |
274 const VideoCaptureSettings& video_capture_settings() const { | 309 const VideoCaptureSettings& video_capture_settings() const { |
275 return video_capture_settings_; | 310 return video_capture_settings_; |
276 } | 311 } |
277 void SetVideoCaptureSettings(const VideoCaptureSettings& settings, | 312 void SetVideoCaptureSettings(const VideoCaptureSettings& settings, |
278 bool is_content_capture) { | 313 bool is_content_capture) { |
279 DCHECK(settings.HasValue()); | 314 DCHECK(settings.HasValue()); |
280 is_video_content_capture_ = is_content_capture; | 315 is_video_content_capture_ = is_content_capture; |
281 video_capture_settings_ = settings; | 316 video_capture_settings_ = settings; |
282 } | 317 } |
(...skipping 15 matching lines...) Expand all Loading... | |
298 MediaStreamRequestResult result, | 333 MediaStreamRequestResult result, |
299 const blink::WebString& result_name); | 334 const blink::WebString& result_name); |
300 | 335 |
301 // Cheks if the sources for all tracks have been started and if so, | 336 // Cheks if the sources for all tracks have been started and if so, |
302 // invoke the |ready_callback_|. Note that the caller should expect | 337 // invoke the |ready_callback_|. Note that the caller should expect |
303 // that |this| might be deleted when the function returns. | 338 // that |this| might be deleted when the function returns. |
304 void CheckAllTracksStarted(); | 339 void CheckAllTracksStarted(); |
305 | 340 |
306 const int request_id_; | 341 const int request_id_; |
307 State state_; | 342 State state_; |
308 bool enable_automatic_output_device_selection_; | 343 // TODO(guidou): Remove this field. http://crbug.com/706408 |
344 bool legacy_enable_automatic_output_device_selection_; | |
345 AudioCaptureSettings audio_capture_settings_; | |
346 bool is_audio_content_capture_; | |
309 VideoCaptureSettings video_capture_settings_; | 347 VideoCaptureSettings video_capture_settings_; |
310 bool is_video_content_capture_; | 348 bool is_video_content_capture_; |
311 blink::WebMediaStream web_stream_; | 349 blink::WebMediaStream web_stream_; |
312 const blink::WebUserMediaRequest request_; | 350 const blink::WebUserMediaRequest request_; |
313 StreamControls stream_controls_; | 351 StreamControls stream_controls_; |
314 const bool is_processing_user_gesture_; | 352 const bool is_processing_user_gesture_; |
315 const url::Origin security_origin_; | 353 const url::Origin security_origin_; |
316 ResourcesReady ready_callback_; | 354 ResourcesReady ready_callback_; |
317 MediaStreamRequestResult request_result_; | 355 MediaStreamRequestResult request_result_; |
318 blink::WebString request_result_name_; | 356 blink::WebString request_result_name_; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 } | 421 } |
384 | 422 |
385 void UserMediaClientImpl::MaybeProcessNextRequestInfo() { | 423 void UserMediaClientImpl::MaybeProcessNextRequestInfo() { |
386 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 424 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
387 if (current_request_info_ || pending_request_infos_.empty()) | 425 if (current_request_info_ || pending_request_infos_.empty()) |
388 return; | 426 return; |
389 | 427 |
390 current_request_info_ = std::move(pending_request_infos_.front()); | 428 current_request_info_ = std::move(pending_request_infos_.front()); |
391 pending_request_infos_.pop_front(); | 429 pending_request_infos_.pop_front(); |
392 | 430 |
393 // TODO(guidou): Request audio and video capabilities in parallel. | 431 // TODO(guidou): Set up audio and video in parallel. |
394 if (current_request_info_->request().Audio()) { | 432 if (current_request_info_->request().Audio()) { |
395 bool request_audio_input_devices = false; | 433 if (IsOldAudioConstraints()) |
396 // TODO(guidou): Implement spec-compliant device selection for audio. See | 434 LegacySetupAudioInput(); |
397 // http://crbug.com/623104. | 435 else |
398 CopyConstraintsToTrackControls( | 436 SetupAudioInput(current_request_info_->request()); |
399 current_request_info_->request().AudioConstraints(), | 437 return; |
400 ¤t_request_info_->stream_controls()->audio, | 438 } |
401 &request_audio_input_devices); | 439 SetupVideoInput(current_request_info_->request()); |
402 CopyHotwordAndLocalEchoToStreamControls( | 440 } |
403 current_request_info_->request().AudioConstraints(), | |
404 current_request_info_->stream_controls()); | |
405 // Check if this input device should be used to select a matching output | |
406 // device for audio rendering. | |
407 bool enable_automatic_output_device_selection = false; | |
408 GetConstraintValueAsBoolean( | |
409 current_request_info_->request().AudioConstraints(), | |
410 &blink::WebMediaTrackConstraintSet::render_to_associated_sink, | |
411 &enable_automatic_output_device_selection); | |
412 current_request_info_->set_enable_automatic_output_device_selection( | |
413 enable_automatic_output_device_selection); | |
414 | 441 |
415 if (request_audio_input_devices) { | 442 void UserMediaClientImpl::LegacySetupAudioInput() { |
416 GetMediaDevicesDispatcher()->EnumerateDevices( | 443 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
417 true /* audio_input */, false /* video_input */, | 444 DCHECK(IsOldAudioConstraints()); |
418 false /* audio_output */, | 445 DCHECK(current_request_info_); |
419 base::Bind(&UserMediaClientImpl::SelectAudioInputDevice, | 446 DCHECK(current_request_info_->request().Audio()); |
420 weak_factory_.GetWeakPtr(), | 447 |
421 current_request_info_->request())); | 448 bool request_audio_input_devices = false; |
422 return; | 449 CopyConstraintsToTrackControls( |
423 } | 450 current_request_info_->request().AudioConstraints(), |
451 ¤t_request_info_->stream_controls()->audio, | |
452 &request_audio_input_devices); | |
453 CopyHotwordAndLocalEchoToStreamControls( | |
454 current_request_info_->request().AudioConstraints(), | |
455 current_request_info_->stream_controls()); | |
456 // Check if this input device should be used to select a matching output | |
457 // device for audio rendering. | |
458 bool enable_automatic_output_device_selection = false; | |
459 GetConstraintValueAsBoolean( | |
460 current_request_info_->request().AudioConstraints(), | |
461 &blink::WebMediaTrackConstraintSet::render_to_associated_sink, | |
462 &enable_automatic_output_device_selection); | |
463 current_request_info_->set_legacy_enable_automatic_output_device_selection( | |
464 enable_automatic_output_device_selection); | |
465 | |
466 if (request_audio_input_devices) { | |
467 GetMediaDevicesDispatcher()->EnumerateDevices( | |
468 true /* audio_input */, false /* video_input */, | |
469 false /* audio_output */, | |
470 base::Bind(&UserMediaClientImpl::LegacySelectAudioInputDevice, | |
471 weak_factory_.GetWeakPtr(), | |
472 current_request_info_->request())); | |
473 return; | |
424 } | 474 } |
425 | 475 |
426 SetupVideoInput(current_request_info_->request()); | 476 SetupVideoInput(current_request_info_->request()); |
427 } | 477 } |
428 | 478 |
429 void UserMediaClientImpl::SelectAudioInputDevice( | 479 void UserMediaClientImpl::LegacySelectAudioInputDevice( |
430 const blink::WebUserMediaRequest& user_media_request, | 480 const blink::WebUserMediaRequest& user_media_request, |
431 const EnumerationResult& device_enumeration) { | 481 const EnumerationResult& device_enumeration) { |
432 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 482 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
483 DCHECK(IsOldAudioConstraints()); | |
433 if (!IsCurrentRequestInfo(user_media_request)) | 484 if (!IsCurrentRequestInfo(user_media_request)) |
434 return; | 485 return; |
435 | 486 |
436 auto& audio_controls = current_request_info_->stream_controls()->audio; | 487 auto& audio_controls = current_request_info_->stream_controls()->audio; |
437 DCHECK(audio_controls.requested); | 488 DCHECK(audio_controls.requested); |
438 DCHECK(IsDeviceSource(audio_controls.stream_source)); | 489 DCHECK(IsDeviceSource(audio_controls.stream_source)); |
439 | 490 |
440 if (!PickDeviceId(user_media_request.AudioConstraints(), | 491 if (!PickDeviceId(user_media_request.AudioConstraints(), |
441 device_enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT], | 492 device_enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT], |
442 &audio_controls.device_id)) { | 493 &audio_controls.device_id)) { |
443 GetUserMediaRequestFailed(user_media_request, MEDIA_DEVICE_NO_HARDWARE, ""); | 494 GetUserMediaRequestFailed(user_media_request, MEDIA_DEVICE_NO_HARDWARE, ""); |
444 return; | 495 return; |
445 } | 496 } |
446 | 497 |
447 SetupVideoInput(user_media_request); | 498 SetupVideoInput(user_media_request); |
448 } | 499 } |
449 | 500 |
501 void UserMediaClientImpl::SetupAudioInput( | |
502 const blink::WebUserMediaRequest& user_media_request) { | |
503 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
504 DCHECK(!IsOldAudioConstraints()); | |
505 DCHECK(user_media_request.Audio()); | |
506 if (!IsCurrentRequestInfo(user_media_request)) | |
507 return; | |
508 | |
509 auto& audio_controls = current_request_info_->stream_controls()->audio; | |
510 InitializeTrackControls(user_media_request.AudioConstraints(), | |
511 &audio_controls); | |
512 if (IsDeviceSource(audio_controls.stream_source)) { | |
513 GetMediaDevicesDispatcher()->GetAudioInputCapabilities( | |
514 base::Bind(&UserMediaClientImpl::SelectAudioSettings, | |
515 weak_factory_.GetWeakPtr(), user_media_request)); | |
516 } else { | |
517 if (!IsValidAudioContentSource(audio_controls.stream_source)) { | |
518 blink::WebString failed_constraint_name = | |
519 blink::WebString::FromASCII(user_media_request.AudioConstraints() | |
520 .Basic() | |
521 .media_stream_source.GetName()); | |
522 MediaStreamRequestResult result = MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; | |
523 GetUserMediaRequestFailed(user_media_request, result, | |
524 failed_constraint_name); | |
525 return; | |
526 } | |
527 SelectAudioSettings(user_media_request, AudioDeviceCaptureCapabilities()); | |
528 } | |
529 } | |
530 | |
531 void UserMediaClientImpl::SelectAudioSettings( | |
532 const blink::WebUserMediaRequest& user_media_request, | |
533 std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> | |
534 audio_input_capabilities) { | |
535 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
536 DCHECK(!IsOldAudioConstraints()); | |
537 if (!IsCurrentRequestInfo(user_media_request)) | |
538 return; | |
539 | |
540 DCHECK(current_request_info_->stream_controls()->audio.requested); | |
541 auto settings = | |
542 SelectSettingsAudioCapture(std::move(audio_input_capabilities), | |
543 user_media_request.AudioConstraints()); | |
544 if (!settings.HasValue()) { | |
545 blink::WebString failed_constraint_name = | |
546 blink::WebString::FromASCII(settings.failed_constraint_name()); | |
547 MediaStreamRequestResult result = | |
548 failed_constraint_name.IsEmpty() | |
549 ? MEDIA_DEVICE_NO_HARDWARE | |
550 : MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; | |
551 GetUserMediaRequestFailed(user_media_request, result, | |
552 failed_constraint_name); | |
553 return; | |
554 } | |
555 current_request_info_->stream_controls()->audio.device_id = | |
556 settings.device_id(); | |
hbos_chromium
2017/06/16 17:27:14
What about ->audio.stream_source?
Guido Urdaneta
2017/06/19 11:56:48
It's set by InitializeTrackControls().
hbos_chromium
2017/06/19 15:14:41
Acknowledged.
| |
557 current_request_info_->stream_controls()->disable_local_echo = | |
558 settings.disable_local_echo(); | |
559 current_request_info_->stream_controls()->hotword_enabled = | |
560 settings.hotword_enabled(); | |
561 current_request_info_->SetAudioCaptureSettings( | |
562 settings, | |
563 !IsDeviceSource( | |
564 current_request_info_->stream_controls()->audio.stream_source)); | |
565 | |
566 SetupVideoInput(user_media_request); | |
567 } | |
568 | |
450 void UserMediaClientImpl::SetupVideoInput( | 569 void UserMediaClientImpl::SetupVideoInput( |
451 const blink::WebUserMediaRequest& user_media_request) { | 570 const blink::WebUserMediaRequest& user_media_request) { |
452 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 571 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
453 if (!IsCurrentRequestInfo(user_media_request)) | 572 if (!IsCurrentRequestInfo(user_media_request)) |
454 return; | 573 return; |
455 | 574 |
456 if (!user_media_request.Video()) { | 575 if (!user_media_request.Video()) { |
457 GenerateStreamForCurrentRequestInfo(); | 576 GenerateStreamForCurrentRequestInfo(); |
458 return; | 577 return; |
459 } | 578 } |
460 auto& video_controls = current_request_info_->stream_controls()->video; | 579 auto& video_controls = current_request_info_->stream_controls()->video; |
461 InitializeTrackControls(user_media_request.VideoConstraints(), | 580 InitializeTrackControls(user_media_request.VideoConstraints(), |
462 &video_controls); | 581 &video_controls); |
463 if (IsDeviceSource(video_controls.stream_source)) { | 582 if (IsDeviceSource(video_controls.stream_source)) { |
464 GetMediaDevicesDispatcher()->GetVideoInputCapabilities( | 583 GetMediaDevicesDispatcher()->GetVideoInputCapabilities( |
465 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSettings, | 584 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSettings, |
466 weak_factory_.GetWeakPtr(), user_media_request)); | 585 weak_factory_.GetWeakPtr(), user_media_request)); |
467 } else { | 586 } else { |
587 if (!IsValidVideoContentSource(video_controls.stream_source)) { | |
588 blink::WebString failed_constraint_name = | |
589 blink::WebString::FromASCII(user_media_request.VideoConstraints() | |
590 .Basic() | |
591 .media_stream_source.GetName()); | |
592 MediaStreamRequestResult result = MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; | |
593 GetUserMediaRequestFailed(user_media_request, result, | |
594 failed_constraint_name); | |
595 return; | |
hbos_chromium
2017/06/16 17:27:14
Was this a drive-by fix?
Guido Urdaneta
2017/06/19 11:56:48
Yes.
| |
596 } | |
468 base::PostTaskAndReplyWithResult( | 597 base::PostTaskAndReplyWithResult( |
469 worker_task_runner_.get(), FROM_HERE, | 598 worker_task_runner_.get(), FROM_HERE, |
470 base::Bind(&SelectSettingsVideoContentCapture, | 599 base::Bind(&SelectSettingsVideoContentCapture, |
471 user_media_request.VideoConstraints(), | 600 user_media_request.VideoConstraints(), |
472 video_controls.stream_source), | 601 video_controls.stream_source), |
473 base::Bind(&UserMediaClientImpl::FinalizeSelectVideoContentSettings, | 602 base::Bind(&UserMediaClientImpl::FinalizeSelectVideoContentSettings, |
474 weak_factory_.GetWeakPtr(), user_media_request)); | 603 weak_factory_.GetWeakPtr(), user_media_request)); |
475 } | 604 } |
476 } | 605 } |
477 | 606 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
533 const blink::WebUserMediaRequest& user_media_request, | 662 const blink::WebUserMediaRequest& user_media_request, |
534 const VideoCaptureSettings& settings) { | 663 const VideoCaptureSettings& settings) { |
535 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 664 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
536 if (!IsCurrentRequestInfo(user_media_request)) | 665 if (!IsCurrentRequestInfo(user_media_request)) |
537 return; | 666 return; |
538 | 667 |
539 if (!settings.HasValue()) { | 668 if (!settings.HasValue()) { |
540 blink::WebString failed_constraint_name = | 669 blink::WebString failed_constraint_name = |
541 blink::WebString::FromASCII(settings.failed_constraint_name()); | 670 blink::WebString::FromASCII(settings.failed_constraint_name()); |
542 DCHECK(!failed_constraint_name.IsEmpty()); | 671 DCHECK(!failed_constraint_name.IsEmpty()); |
543 blink::WebString device_id_constraint_name = blink::WebString::FromASCII( | |
544 user_media_request.VideoConstraints().Basic().device_id.GetName()); | |
545 GetUserMediaRequestFailed(user_media_request, | 672 GetUserMediaRequestFailed(user_media_request, |
546 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, | 673 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, |
547 failed_constraint_name); | 674 failed_constraint_name); |
548 return; | 675 return; |
549 } | 676 } |
550 current_request_info_->stream_controls()->video.device_id = | 677 current_request_info_->stream_controls()->video.device_id = |
551 settings.device_id(); | 678 settings.device_id(); |
552 current_request_info_->SetVideoCaptureSettings(settings, | 679 current_request_info_->SetVideoCaptureSettings(settings, |
553 true /* is_content_capture */); | 680 true /* is_content_capture */); |
554 GenerateStreamForCurrentRequestInfo(); | 681 GenerateStreamForCurrentRequestInfo(); |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
840 &UserMediaClientImpl::OnLocalSourceStopped, weak_factory_.GetWeakPtr())); | 967 &UserMediaClientImpl::OnLocalSourceStopped, weak_factory_.GetWeakPtr())); |
841 source.SetExtraData(audio_source); // Takes ownership. | 968 source.SetExtraData(audio_source); // Takes ownership. |
842 return source; | 969 return source; |
843 } | 970 } |
844 | 971 |
845 MediaStreamAudioSource* UserMediaClientImpl::CreateAudioSource( | 972 MediaStreamAudioSource* UserMediaClientImpl::CreateAudioSource( |
846 const StreamDeviceInfo& device, | 973 const StreamDeviceInfo& device, |
847 const blink::WebMediaConstraints& constraints, | 974 const blink::WebMediaConstraints& constraints, |
848 const MediaStreamSource::ConstraintsCallback& source_ready) { | 975 const MediaStreamSource::ConstraintsCallback& source_ready) { |
849 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 976 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
977 DCHECK(current_request_info_); | |
850 // If the audio device is a loopback device (for screen capture), or if the | 978 // If the audio device is a loopback device (for screen capture), or if the |
851 // constraints/effects parameters indicate no audio processing is needed, | 979 // constraints/effects parameters indicate no audio processing is needed, |
852 // create an efficient, direct-path MediaStreamAudioSource instance. | 980 // create an efficient, direct-path MediaStreamAudioSource instance. |
981 AudioProcessingProperties audio_processing_properties = | |
982 IsOldAudioConstraints() ? AudioProcessingProperties::FromConstraints( | |
983 constraints, device.device.input) | |
984 : current_request_info_->audio_capture_settings() | |
985 .audio_processing_properties(); | |
853 if (IsScreenCaptureMediaType(device.device.type) || | 986 if (IsScreenCaptureMediaType(device.device.type) || |
854 !MediaStreamAudioProcessor::WouldModifyAudio( | 987 !MediaStreamAudioProcessor::WouldModifyAudio( |
855 constraints, device.device.input.effects)) { | 988 audio_processing_properties)) { |
856 return new LocalMediaStreamAudioSource(RenderFrameObserver::routing_id(), | 989 return new LocalMediaStreamAudioSource(RenderFrameObserver::routing_id(), |
857 device, source_ready); | 990 device, source_ready); |
858 } | 991 } |
859 | 992 |
860 // The audio device is not associated with screen capture and also requires | 993 // The audio device is not associated with screen capture and also requires |
861 // processing. | 994 // processing. |
862 ProcessedLocalAudioSource* source = new ProcessedLocalAudioSource( | 995 ProcessedLocalAudioSource* source = new ProcessedLocalAudioSource( |
863 RenderFrameObserver::routing_id(), device, constraints, source_ready, | 996 RenderFrameObserver::routing_id(), device, audio_processing_properties, |
864 dependency_factory_); | 997 source_ready, dependency_factory_); |
865 return source; | 998 return source; |
866 } | 999 } |
867 | 1000 |
868 MediaStreamVideoSource* UserMediaClientImpl::CreateVideoSource( | 1001 MediaStreamVideoSource* UserMediaClientImpl::CreateVideoSource( |
869 const StreamDeviceInfo& device, | 1002 const StreamDeviceInfo& device, |
870 const MediaStreamSource::SourceStoppedCallback& stop_callback) { | 1003 const MediaStreamSource::SourceStoppedCallback& stop_callback) { |
871 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 1004 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
872 DCHECK(current_request_info_); | 1005 DCHECK(current_request_info_); |
873 if (IsOldVideoConstraints()) { | 1006 if (IsOldVideoConstraints()) { |
874 return new MediaStreamVideoCapturerSource(stop_callback, device, | 1007 return new MediaStreamVideoCapturerSource(stop_callback, device, |
(...skipping 24 matching lines...) Expand all Loading... | |
899 | 1032 |
900 void UserMediaClientImpl::CreateAudioTracks( | 1033 void UserMediaClientImpl::CreateAudioTracks( |
901 const StreamDeviceInfoArray& devices, | 1034 const StreamDeviceInfoArray& devices, |
902 const blink::WebMediaConstraints& constraints, | 1035 const blink::WebMediaConstraints& constraints, |
903 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks) { | 1036 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks) { |
904 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 1037 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
905 DCHECK(current_request_info_); | 1038 DCHECK(current_request_info_); |
906 DCHECK_EQ(devices.size(), webkit_tracks->size()); | 1039 DCHECK_EQ(devices.size(), webkit_tracks->size()); |
907 | 1040 |
908 StreamDeviceInfoArray overridden_audio_array = devices; | 1041 StreamDeviceInfoArray overridden_audio_array = devices; |
909 if (!current_request_info_->enable_automatic_output_device_selection()) { | 1042 bool render_to_associated_sink = |
1043 IsOldAudioConstraints() | |
1044 ? current_request_info_ | |
1045 ->legacy_enable_automatic_output_device_selection() | |
1046 : current_request_info_->audio_capture_settings().HasValue() && | |
1047 current_request_info_->audio_capture_settings() | |
1048 .render_to_associated_sink(); | |
1049 if (!render_to_associated_sink) { | |
910 // If the GetUserMedia request did not explicitly set the constraint | 1050 // If the GetUserMedia request did not explicitly set the constraint |
911 // kMediaStreamRenderToAssociatedSink, the output device parameters must | 1051 // kMediaStreamRenderToAssociatedSink, the output device parameters must |
912 // be removed. | 1052 // be removed. |
913 for (auto& device_info : overridden_audio_array) { | 1053 for (auto& device_info : overridden_audio_array) { |
914 device_info.device.matched_output_device_id = ""; | 1054 device_info.device.matched_output_device_id = ""; |
915 device_info.device.matched_output = | 1055 device_info.device.matched_output = |
916 MediaStreamDevice::AudioDeviceParameters(); | 1056 MediaStreamDevice::AudioDeviceParameters(); |
917 } | 1057 } |
918 } | 1058 } |
919 | 1059 |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1254 const ::mojom::MediaDevicesDispatcherHostPtr& | 1394 const ::mojom::MediaDevicesDispatcherHostPtr& |
1255 UserMediaClientImpl::GetMediaDevicesDispatcher() { | 1395 UserMediaClientImpl::GetMediaDevicesDispatcher() { |
1256 if (!media_devices_dispatcher_) { | 1396 if (!media_devices_dispatcher_) { |
1257 render_frame()->GetRemoteInterfaces()->GetInterface( | 1397 render_frame()->GetRemoteInterfaces()->GetInterface( |
1258 mojo::MakeRequest(&media_devices_dispatcher_)); | 1398 mojo::MakeRequest(&media_devices_dispatcher_)); |
1259 } | 1399 } |
1260 | 1400 |
1261 return media_devices_dispatcher_; | 1401 return media_devices_dispatcher_; |
1262 } | 1402 } |
1263 | 1403 |
1404 const AudioCaptureSettings& | |
1405 UserMediaClientImpl::AudioCaptureSettingsForCurrentRequest() const { | |
1406 DCHECK(current_request_info_); | |
1407 return current_request_info_->audio_capture_settings(); | |
1408 } | |
1409 | |
1410 const VideoCaptureSettings& | |
1411 UserMediaClientImpl::VideoCaptureSettingsForCurrentRequest() const { | |
1412 DCHECK(current_request_info_); | |
1413 return current_request_info_->video_capture_settings(); | |
1414 } | |
1415 | |
1264 base::Optional<bool> | 1416 base::Optional<bool> |
1265 UserMediaClientImpl::AutomaticOutputDeviceSelectionEnabledForCurrentRequest() { | 1417 UserMediaClientImpl::AutomaticOutputDeviceSelectionEnabledForCurrentRequest() { |
1266 if (!current_request_info_) | 1418 if (!current_request_info_) |
1267 return base::Optional<bool>(); | 1419 return base::Optional<bool>(); |
1268 | 1420 |
1269 return base::Optional<bool>( | 1421 return base::Optional<bool>( |
1270 current_request_info_->enable_automatic_output_device_selection()); | 1422 current_request_info_->legacy_enable_automatic_output_device_selection()); |
1271 } | 1423 } |
1272 | 1424 |
1273 void UserMediaClientImpl::OnDestruct() { | 1425 void UserMediaClientImpl::OnDestruct() { |
1274 delete this; | 1426 delete this; |
1275 } | 1427 } |
1276 | 1428 |
1277 UserMediaClientImpl::UserMediaRequestInfo::UserMediaRequestInfo( | 1429 UserMediaClientImpl::UserMediaRequestInfo::UserMediaRequestInfo( |
1278 int request_id, | 1430 int request_id, |
1279 const blink::WebUserMediaRequest& request, | 1431 const blink::WebUserMediaRequest& request, |
1280 bool is_processing_user_gesture, | 1432 bool is_processing_user_gesture, |
1281 const url::Origin& security_origin) | 1433 const url::Origin& security_origin) |
1282 : request_id_(request_id), | 1434 : request_id_(request_id), |
1283 state_(State::NOT_SENT_FOR_GENERATION), | 1435 state_(State::NOT_SENT_FOR_GENERATION), |
1284 enable_automatic_output_device_selection_(false), | 1436 legacy_enable_automatic_output_device_selection_(false), |
1437 is_audio_content_capture_(false), | |
1285 is_video_content_capture_(false), | 1438 is_video_content_capture_(false), |
1286 request_(request), | 1439 request_(request), |
1287 is_processing_user_gesture_(is_processing_user_gesture), | 1440 is_processing_user_gesture_(is_processing_user_gesture), |
1288 security_origin_(security_origin), | 1441 security_origin_(security_origin), |
1289 request_result_(MEDIA_DEVICE_OK), | 1442 request_result_(MEDIA_DEVICE_OK), |
1290 request_result_name_("") {} | 1443 request_result_name_("") {} |
1291 | 1444 |
1292 void UserMediaClientImpl::UserMediaRequestInfo::StartAudioTrack( | 1445 void UserMediaClientImpl::UserMediaRequestInfo::StartAudioTrack( |
1293 const blink::WebMediaStreamTrack& track, | 1446 const blink::WebMediaStreamTrack& track, |
1294 bool is_pending) { | 1447 bool is_pending) { |
1295 DCHECK(track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio); | 1448 DCHECK(track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio); |
1449 DCHECK(request_.Audio()); | |
1450 #if DCHECK_IS_ON() | |
1451 if (!IsOldAudioConstraints()) | |
1452 DCHECK(audio_capture_settings_.HasValue()); | |
1453 #endif | |
1296 MediaStreamAudioSource* native_source = | 1454 MediaStreamAudioSource* native_source = |
1297 MediaStreamAudioSource::From(track.Source()); | 1455 MediaStreamAudioSource::From(track.Source()); |
1298 // Add the source as pending since OnTrackStarted will expect it to be there. | 1456 // Add the source as pending since OnTrackStarted will expect it to be there. |
1299 sources_waiting_for_callback_.push_back(native_source); | 1457 sources_waiting_for_callback_.push_back(native_source); |
1300 | 1458 |
1301 sources_.push_back(track.Source()); | 1459 sources_.push_back(track.Source()); |
1302 bool connected = native_source->ConnectToTrack(track); | 1460 bool connected = native_source->ConnectToTrack(track); |
1303 if (!is_pending) { | 1461 if (!is_pending) { |
1304 OnTrackStarted( | 1462 OnTrackStarted( |
1305 native_source, | 1463 native_source, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1379 const blink::WebString& result_name) { | 1537 const blink::WebString& result_name) { |
1380 // Check if we're waiting to be notified of this source. If not, then we'll | 1538 // Check if we're waiting to be notified of this source. If not, then we'll |
1381 // ignore the notification. | 1539 // ignore the notification. |
1382 auto found = std::find(sources_waiting_for_callback_.begin(), | 1540 auto found = std::find(sources_waiting_for_callback_.begin(), |
1383 sources_waiting_for_callback_.end(), source); | 1541 sources_waiting_for_callback_.end(), source); |
1384 if (found != sources_waiting_for_callback_.end()) | 1542 if (found != sources_waiting_for_callback_.end()) |
1385 OnTrackStarted(source, result, result_name); | 1543 OnTrackStarted(source, result, result_name); |
1386 } | 1544 } |
1387 | 1545 |
1388 } // namespace content | 1546 } // namespace content |
OLD | NEW |