Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: content/renderer/media/user_media_client_impl.cc

Issue 2750163002: Use spec-compliant algorithm for video content-capture deviceId selection in getUserMedia. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/renderer/media/user_media_client_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 342
332 SetupVideoInput(request_id, user_media_request, std::move(controls), 343 SetupVideoInput(request_id, user_media_request, std::move(controls),
333 request_settings); 344 request_settings);
334 } 345 }
335 346
336 void UserMediaClientImpl::SetupVideoInput( 347 void UserMediaClientImpl::SetupVideoInput(
337 int request_id, 348 int request_id,
338 const blink::WebUserMediaRequest& user_media_request, 349 const blink::WebUserMediaRequest& user_media_request,
339 std::unique_ptr<StreamControls> controls, 350 std::unique_ptr<StreamControls> controls,
340 const RequestSettings& request_settings) { 351 const RequestSettings& request_settings) {
341 if (user_media_request.video()) { 352 if (!user_media_request.video()) {
342 bool ignore; 353 FinalizeRequestUserMedia(request_id, user_media_request,
343 CopyConstraintsToTrackControls(user_media_request.videoConstraints(), 354 std::move(controls), request_settings);
344 &controls->video, &ignore); 355 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 } 356 }
354 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), 357 InitializeTrackControls(user_media_request.videoConstraints(),
355 request_settings); 358 &controls->video);
359 if (IsDeviceSource(controls->video.stream_source)) {
360 GetMediaDevicesDispatcher()->GetVideoInputCapabilities(
361 request_settings.security_origin,
362 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSourceSettings,
363 weak_factory_.GetWeakPtr(), request_id, user_media_request,
364 base::Passed(&controls), request_settings));
365 } else {
366 base::PostTaskAndReplyWithResult(
367 worker_task_runner_.get(), FROM_HERE,
368 base::Bind(&SelectVideoContentCaptureSourceSettings,
369 user_media_request.videoConstraints()),
370 base::Bind(
371 &UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings,
372 weak_factory_.GetWeakPtr(), request_id, user_media_request,
373 base::Passed(&controls), request_settings));
374 }
356 } 375 }
357 376
358 void UserMediaClientImpl::SelectVideoDeviceSourceSettings( 377 void UserMediaClientImpl::SelectVideoDeviceSourceSettings(
359 int request_id, 378 int request_id,
360 const blink::WebUserMediaRequest& user_media_request, 379 const blink::WebUserMediaRequest& user_media_request,
361 std::unique_ptr<StreamControls> controls, 380 std::unique_ptr<StreamControls> controls,
362 const RequestSettings& request_settings, 381 const RequestSettings& request_settings,
363 std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> 382 std::vector<::mojom::VideoInputDeviceCapabilitiesPtr>
364 video_input_capabilities) { 383 video_input_capabilities) {
365 DCHECK(CalledOnValidThread()); 384 DCHECK(CalledOnValidThread());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 GetUserMediaRequestFailed(user_media_request, 429 GetUserMediaRequestFailed(user_media_request,
411 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, 430 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED,
412 failed_constraint_name); 431 failed_constraint_name);
413 return; 432 return;
414 } 433 }
415 } 434 }
416 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), 435 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls),
417 request_settings); 436 request_settings);
418 } 437 }
419 438
439 void UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings(
440 int request_id,
441 const blink::WebUserMediaRequest& user_media_request,
442 std::unique_ptr<StreamControls> controls,
443 const RequestSettings& request_settings,
444 const VideoContentCaptureSourceSelectionResult& selection_result) {
445 DCHECK(CalledOnValidThread());
446 if (!selection_result.HasValue()) {
447 blink::WebString failed_constraint_name =
448 blink::WebString::fromASCII(selection_result.failed_constraint_name());
449 DCHECK(!failed_constraint_name.isEmpty());
450 blink::WebString device_id_constraint_name = blink::WebString::fromASCII(
451 user_media_request.videoConstraints().basic().deviceId.name());
452 GetUserMediaRequestFailed(user_media_request,
453 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED,
454 failed_constraint_name);
455 return;
456 }
457 controls->video.device_id = selection_result.device_id();
458 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls),
459 request_settings);
460 }
461
420 void UserMediaClientImpl::FinalizeRequestUserMedia( 462 void UserMediaClientImpl::FinalizeRequestUserMedia(
421 int request_id, 463 int request_id,
422 const blink::WebUserMediaRequest& user_media_request, 464 const blink::WebUserMediaRequest& user_media_request,
423 std::unique_ptr<StreamControls> controls, 465 std::unique_ptr<StreamControls> controls,
424 const RequestSettings& request_settings) { 466 const RequestSettings& request_settings) {
425 DCHECK(CalledOnValidThread()); 467 DCHECK(CalledOnValidThread());
426 468
427 WebRtcLogMessage( 469 WebRtcLogMessage(
428 base::StringPrintf("MSI::requestUserMedia. request_id=%d" 470 base::StringPrintf("MSI::requestUserMedia. request_id=%d"
429 ", audio source id=%s" 471 ", audio source id=%s"
430 ", video source id=%s", 472 ", video source id=%s",
431 request_id, controls->audio.device_id.c_str(), 473 request_id, controls->audio.device_id.c_str(),
432 controls->video.device_id.c_str())); 474 controls->video.device_id.c_str()));
hbos_chromium 2017/03/17 11:53:28 I noticed we do FinalizeRequestUserMedia if !video
Guido Urdaneta 2017/03/17 12:33:42 If audio and video are both false, the constraints
hbos_chromium 2017/03/17 15:27:39 OK. Can we DCHECK audio or video in the public req
Guido Urdaneta 2017/03/17 18:13:46 Done.
433 475
434 user_media_requests_.push_back(base::MakeUnique<UserMediaRequestInfo>( 476 user_media_requests_.push_back(base::MakeUnique<UserMediaRequestInfo>(
435 request_id, user_media_request, 477 request_id, user_media_request,
436 request_settings.enable_automatic_audio_output_device_selection)); 478 request_settings.enable_automatic_audio_output_device_selection));
437 479
438 media_stream_dispatcher_->GenerateStream( 480 media_stream_dispatcher_->GenerateStream(
439 request_id, weak_factory_.GetWeakPtr(), *controls, 481 request_id, weak_factory_.GetWeakPtr(), *controls,
440 request_settings.security_origin, 482 request_settings.security_origin,
441 request_settings.is_processing_user_gesture); 483 request_settings.is_processing_user_gesture);
442 } 484 }
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 sources_waiting_for_callback_.end(), source); 1288 sources_waiting_for_callback_.end(), source);
1247 if (found != sources_waiting_for_callback_.end()) 1289 if (found != sources_waiting_for_callback_.end())
1248 OnTrackStarted(source, result, result_name); 1290 OnTrackStarted(source, result, result_name);
1249 } 1291 }
1250 1292
1251 void UserMediaClientImpl::OnDestruct() { 1293 void UserMediaClientImpl::OnDestruct() {
1252 delete this; 1294 delete this;
1253 } 1295 }
1254 1296
1255 } // namespace content 1297 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/user_media_client_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698