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/hash.h" | 12 #include "base/hash.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
21 #include "base/task_runner.h" | 21 #include "base/task_runner.h" |
22 #include "base/task_runner_util.h" | 22 #include "base/task_runner_util.h" |
23 #include "base/threading/thread_task_runner_handle.h" | 23 #include "base/threading/thread_task_runner_handle.h" |
24 #include "build/build_config.h" | 24 #include "build/build_config.h" |
25 #include "content/public/renderer/render_frame.h" | 25 #include "content/public/renderer/render_frame.h" |
26 #include "content/renderer/media/local_media_stream_audio_source.h" | 26 #include "content/renderer/media/local_media_stream_audio_source.h" |
27 #include "content/renderer/media/media_stream.h" | 27 #include "content/renderer/media/media_stream.h" |
28 #include "content/renderer/media/media_stream_constraints_util.h" | 28 #include "content/renderer/media/media_stream_constraints_util.h" |
| 29 #include "content/renderer/media/media_stream_constraints_util_video_content.h" |
29 #include "content/renderer/media/media_stream_constraints_util_video_device.h" | 30 #include "content/renderer/media/media_stream_constraints_util_video_device.h" |
30 #include "content/renderer/media/media_stream_dispatcher.h" | 31 #include "content/renderer/media/media_stream_dispatcher.h" |
31 #include "content/renderer/media/media_stream_video_capturer_source.h" | 32 #include "content/renderer/media/media_stream_video_capturer_source.h" |
32 #include "content/renderer/media/media_stream_video_track.h" | 33 #include "content/renderer/media/media_stream_video_track.h" |
33 #include "content/renderer/media/peer_connection_tracker.h" | 34 #include "content/renderer/media/peer_connection_tracker.h" |
34 #include "content/renderer/media/webrtc/processed_local_audio_source.h" | 35 #include "content/renderer/media/webrtc/processed_local_audio_source.h" |
35 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" | 36 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" |
36 #include "content/renderer/media/webrtc_logging.h" | 37 #include "content/renderer/media/webrtc_logging.h" |
37 #include "content/renderer/media/webrtc_uma_histograms.h" | 38 #include "content/renderer/media/webrtc_uma_histograms.h" |
38 #include "content/renderer/render_thread_impl.h" | 39 #include "content/renderer/render_thread_impl.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 } | 123 } |
123 | 124 |
124 // No valid alternate device ID found. Select default device. | 125 // No valid alternate device ID found. Select default device. |
125 return true; | 126 return true; |
126 } | 127 } |
127 | 128 |
128 bool IsDeviceSource(const std::string& source) { | 129 bool IsDeviceSource(const std::string& source) { |
129 return source.empty(); | 130 return source.empty(); |
130 } | 131 } |
131 | 132 |
| 133 // TODO(guidou): Remove once audio constraints are processed with spec-compliant |
| 134 // algorithm. See http://crbug.com/657733. |
132 void CopyConstraintsToTrackControls( | 135 void CopyConstraintsToTrackControls( |
133 const blink::WebMediaConstraints& constraints, | 136 const blink::WebMediaConstraints& constraints, |
134 TrackControls* track_controls, | 137 TrackControls* track_controls, |
135 bool* request_devices) { | 138 bool* request_devices) { |
136 DCHECK(!constraints.isNull()); | 139 DCHECK(!constraints.isNull()); |
137 track_controls->requested = true; | 140 track_controls->requested = true; |
138 CopyFirstString(constraints.basic().mediaStreamSource, | 141 CopyFirstString(constraints.basic().mediaStreamSource, |
139 &track_controls->stream_source); | 142 &track_controls->stream_source); |
140 if (IsDeviceSource(track_controls->stream_source)) { | 143 if (IsDeviceSource(track_controls->stream_source)) { |
141 bool request_devices_advanced = false; | 144 bool request_devices_advanced = false; |
142 for (const auto& advanced : constraints.advanced()) { | 145 for (const auto& advanced : constraints.advanced()) { |
143 if (!advanced.deviceId.isEmpty()) { | 146 if (!advanced.deviceId.isEmpty()) { |
144 request_devices_advanced = true; | 147 request_devices_advanced = true; |
145 break; | 148 break; |
146 } | 149 } |
147 } | 150 } |
148 *request_devices = | 151 *request_devices = |
149 request_devices_advanced || !constraints.basic().deviceId.isEmpty(); | 152 request_devices_advanced || !constraints.basic().deviceId.isEmpty(); |
150 } else { | 153 } else { |
151 CopyFirstString(constraints.basic().deviceId, &track_controls->device_id); | 154 CopyFirstString(constraints.basic().deviceId, &track_controls->device_id); |
152 *request_devices = false; | 155 *request_devices = false; |
153 } | 156 } |
154 } | 157 } |
155 | 158 |
| 159 void InitializeTrackControls(const blink::WebMediaConstraints& constraints, |
| 160 TrackControls* track_controls) { |
| 161 DCHECK(!constraints.isNull()); |
| 162 track_controls->requested = true; |
| 163 CopyFirstString(constraints.basic().mediaStreamSource, |
| 164 &track_controls->stream_source); |
| 165 } |
| 166 |
156 void CopyHotwordAndLocalEchoToStreamControls( | 167 void CopyHotwordAndLocalEchoToStreamControls( |
157 const blink::WebMediaConstraints& audio_constraints, | 168 const blink::WebMediaConstraints& audio_constraints, |
158 StreamControls* controls) { | 169 StreamControls* controls) { |
159 if (audio_constraints.isNull()) | 170 if (audio_constraints.isNull()) |
160 return; | 171 return; |
161 | 172 |
162 if (audio_constraints.basic().hotwordEnabled.hasExact()) { | 173 if (audio_constraints.basic().hotwordEnabled.hasExact()) { |
163 controls->hotword_enabled = | 174 controls->hotword_enabled = |
164 audio_constraints.basic().hotwordEnabled.exact(); | 175 audio_constraints.basic().hotwordEnabled.exact(); |
165 } else { | 176 } else { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 } | 264 } |
254 | 265 |
255 void UserMediaClientImpl::requestUserMedia( | 266 void UserMediaClientImpl::requestUserMedia( |
256 const blink::WebUserMediaRequest& user_media_request) { | 267 const blink::WebUserMediaRequest& user_media_request) { |
257 // Save histogram data so we can see how much GetUserMedia is used. | 268 // Save histogram data so we can see how much GetUserMedia is used. |
258 // The histogram counts the number of calls to the JS API | 269 // The histogram counts the number of calls to the JS API |
259 // webGetUserMedia. | 270 // webGetUserMedia. |
260 UpdateWebRTCMethodCount(WEBKIT_GET_USER_MEDIA); | 271 UpdateWebRTCMethodCount(WEBKIT_GET_USER_MEDIA); |
261 DCHECK(CalledOnValidThread()); | 272 DCHECK(CalledOnValidThread()); |
262 DCHECK(!user_media_request.isNull()); | 273 DCHECK(!user_media_request.isNull()); |
| 274 DCHECK(user_media_request.audio() || user_media_request.video()); |
263 // ownerDocument may be null if we are in a test. | 275 // ownerDocument may be null if we are in a test. |
264 // In that case, it's OK to not check frame(). | 276 // In that case, it's OK to not check frame(). |
265 DCHECK(user_media_request.ownerDocument().isNull() || | 277 DCHECK(user_media_request.ownerDocument().isNull() || |
266 render_frame()->GetWebFrame() == | 278 render_frame()->GetWebFrame() == |
267 static_cast<blink::WebFrame*>( | 279 static_cast<blink::WebFrame*>( |
268 user_media_request.ownerDocument().frame())); | 280 user_media_request.ownerDocument().frame())); |
269 | 281 |
270 if (RenderThreadImpl::current()) { | 282 if (RenderThreadImpl::current()) { |
271 RenderThreadImpl::current()->peer_connection_tracker()->TrackGetUserMedia( | 283 RenderThreadImpl::current()->peer_connection_tracker()->TrackGetUserMedia( |
272 user_media_request); | 284 user_media_request); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 | 343 |
332 SetupVideoInput(request_id, user_media_request, std::move(controls), | 344 SetupVideoInput(request_id, user_media_request, std::move(controls), |
333 request_settings); | 345 request_settings); |
334 } | 346 } |
335 | 347 |
336 void UserMediaClientImpl::SetupVideoInput( | 348 void UserMediaClientImpl::SetupVideoInput( |
337 int request_id, | 349 int request_id, |
338 const blink::WebUserMediaRequest& user_media_request, | 350 const blink::WebUserMediaRequest& user_media_request, |
339 std::unique_ptr<StreamControls> controls, | 351 std::unique_ptr<StreamControls> controls, |
340 const RequestSettings& request_settings) { | 352 const RequestSettings& request_settings) { |
341 if (user_media_request.video()) { | 353 if (!user_media_request.video()) { |
342 bool ignore; | 354 FinalizeRequestUserMedia(request_id, user_media_request, |
343 CopyConstraintsToTrackControls(user_media_request.videoConstraints(), | 355 std::move(controls), request_settings); |
344 &controls->video, &ignore); | 356 return; |
345 if (IsDeviceSource(controls->video.stream_source)) { | |
346 GetMediaDevicesDispatcher()->GetVideoInputCapabilities( | |
347 request_settings.security_origin, | |
348 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSourceSettings, | |
349 weak_factory_.GetWeakPtr(), request_id, user_media_request, | |
350 base::Passed(&controls), request_settings)); | |
351 return; | |
352 } | |
353 } | 357 } |
354 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), | 358 InitializeTrackControls(user_media_request.videoConstraints(), |
355 request_settings); | 359 &controls->video); |
| 360 if (IsDeviceSource(controls->video.stream_source)) { |
| 361 GetMediaDevicesDispatcher()->GetVideoInputCapabilities( |
| 362 request_settings.security_origin, |
| 363 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSourceSettings, |
| 364 weak_factory_.GetWeakPtr(), request_id, user_media_request, |
| 365 base::Passed(&controls), request_settings)); |
| 366 } else { |
| 367 base::PostTaskAndReplyWithResult( |
| 368 worker_task_runner_.get(), FROM_HERE, |
| 369 base::Bind(&SelectVideoContentCaptureSourceSettings, |
| 370 user_media_request.videoConstraints()), |
| 371 base::Bind( |
| 372 &UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings, |
| 373 weak_factory_.GetWeakPtr(), request_id, user_media_request, |
| 374 base::Passed(&controls), request_settings)); |
| 375 } |
356 } | 376 } |
357 | 377 |
358 void UserMediaClientImpl::SelectVideoDeviceSourceSettings( | 378 void UserMediaClientImpl::SelectVideoDeviceSourceSettings( |
359 int request_id, | 379 int request_id, |
360 const blink::WebUserMediaRequest& user_media_request, | 380 const blink::WebUserMediaRequest& user_media_request, |
361 std::unique_ptr<StreamControls> controls, | 381 std::unique_ptr<StreamControls> controls, |
362 const RequestSettings& request_settings, | 382 const RequestSettings& request_settings, |
363 std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> | 383 std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> |
364 video_input_capabilities) { | 384 video_input_capabilities) { |
365 DCHECK(CalledOnValidThread()); | 385 DCHECK(CalledOnValidThread()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 GetUserMediaRequestFailed(user_media_request, | 430 GetUserMediaRequestFailed(user_media_request, |
411 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, | 431 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, |
412 failed_constraint_name); | 432 failed_constraint_name); |
413 return; | 433 return; |
414 } | 434 } |
415 } | 435 } |
416 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), | 436 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), |
417 request_settings); | 437 request_settings); |
418 } | 438 } |
419 | 439 |
| 440 void UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings( |
| 441 int request_id, |
| 442 const blink::WebUserMediaRequest& user_media_request, |
| 443 std::unique_ptr<StreamControls> controls, |
| 444 const RequestSettings& request_settings, |
| 445 const VideoContentCaptureSourceSelectionResult& selection_result) { |
| 446 DCHECK(CalledOnValidThread()); |
| 447 if (!selection_result.HasValue()) { |
| 448 blink::WebString failed_constraint_name = |
| 449 blink::WebString::fromASCII(selection_result.failed_constraint_name()); |
| 450 DCHECK(!failed_constraint_name.isEmpty()); |
| 451 blink::WebString device_id_constraint_name = blink::WebString::fromASCII( |
| 452 user_media_request.videoConstraints().basic().deviceId.name()); |
| 453 GetUserMediaRequestFailed(user_media_request, |
| 454 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, |
| 455 failed_constraint_name); |
| 456 return; |
| 457 } |
| 458 controls->video.device_id = selection_result.device_id(); |
| 459 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), |
| 460 request_settings); |
| 461 } |
| 462 |
420 void UserMediaClientImpl::FinalizeRequestUserMedia( | 463 void UserMediaClientImpl::FinalizeRequestUserMedia( |
421 int request_id, | 464 int request_id, |
422 const blink::WebUserMediaRequest& user_media_request, | 465 const blink::WebUserMediaRequest& user_media_request, |
423 std::unique_ptr<StreamControls> controls, | 466 std::unique_ptr<StreamControls> controls, |
424 const RequestSettings& request_settings) { | 467 const RequestSettings& request_settings) { |
425 DCHECK(CalledOnValidThread()); | 468 DCHECK(CalledOnValidThread()); |
426 | 469 |
427 WebRtcLogMessage( | 470 WebRtcLogMessage( |
428 base::StringPrintf("MSI::requestUserMedia. request_id=%d" | 471 base::StringPrintf("MSI::requestUserMedia. request_id=%d" |
429 ", audio source id=%s" | 472 ", audio source id=%s" |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1247 sources_waiting_for_callback_.end(), source); | 1290 sources_waiting_for_callback_.end(), source); |
1248 if (found != sources_waiting_for_callback_.end()) | 1291 if (found != sources_waiting_for_callback_.end()) |
1249 OnTrackStarted(source, result, result_name); | 1292 OnTrackStarted(source, result, result_name); |
1250 } | 1293 } |
1251 | 1294 |
1252 void UserMediaClientImpl::OnDestruct() { | 1295 void UserMediaClientImpl::OnDestruct() { |
1253 delete this; | 1296 delete this; |
1254 } | 1297 } |
1255 | 1298 |
1256 } // namespace content | 1299 } // namespace content |
OLD | NEW |