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

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

Issue 287383002: Implement getMediaDevices. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 6 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 | Annotate | Revision Log
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/media_stream_impl.h" 5 #include "content/renderer/media/media_stream_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "content/renderer/media/media_stream.h" 13 #include "content/renderer/media/media_stream.h"
14 #include "content/renderer/media/media_stream_audio_source.h" 14 #include "content/renderer/media/media_stream_audio_source.h"
15 #include "content/renderer/media/media_stream_dispatcher.h" 15 #include "content/renderer/media/media_stream_dispatcher.h"
16 #include "content/renderer/media/media_stream_video_capturer_source.h" 16 #include "content/renderer/media/media_stream_video_capturer_source.h"
17 #include "content/renderer/media/media_stream_video_track.h" 17 #include "content/renderer/media/media_stream_video_track.h"
18 #include "content/renderer/media/peer_connection_tracker.h" 18 #include "content/renderer/media/peer_connection_tracker.h"
19 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" 19 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
20 #include "content/renderer/media/webrtc_audio_capturer.h" 20 #include "content/renderer/media/webrtc_audio_capturer.h"
21 #include "content/renderer/media/webrtc_logging.h" 21 #include "content/renderer/media/webrtc_logging.h"
22 #include "content/renderer/media/webrtc_uma_histograms.h" 22 #include "content/renderer/media/webrtc_uma_histograms.h"
23 #include "content/renderer/render_thread_impl.h" 23 #include "content/renderer/render_thread_impl.h"
24 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 24 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
25 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h"
25 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 26 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
26 #include "third_party/WebKit/public/web/WebDocument.h" 27 #include "third_party/WebKit/public/web/WebDocument.h"
27 #include "third_party/WebKit/public/web/WebLocalFrame.h" 28 #include "third_party/WebKit/public/web/WebLocalFrame.h"
28 29
29 namespace content { 30 namespace content {
30 namespace { 31 namespace {
31 32
32 void CopyStreamConstraints(const blink::WebMediaConstraints& constraints, 33 void CopyStreamConstraints(const blink::WebMediaConstraints& constraints,
33 StreamOptions::Constraints* mandatory, 34 StreamOptions::Constraints* mandatory,
34 StreamOptions::Constraints* optional) { 35 StreamOptions::Constraints* optional) {
(...skipping 11 matching lines...) Expand all
46 optional->push_back(StreamOptions::Constraint( 47 optional->push_back(StreamOptions::Constraint(
47 optional_constraints[i].m_name.utf8(), 48 optional_constraints[i].m_name.utf8(),
48 optional_constraints[i].m_value.utf8())); 49 optional_constraints[i].m_value.utf8()));
49 } 50 }
50 } 51 }
51 52
52 static int g_next_request_id = 0; 53 static int g_next_request_id = 0;
53 54
54 } // namespace 55 } // namespace
55 56
57 struct MediaStreamImpl::MediaDevicesRequestInfo {
58 MediaDevicesRequestInfo(const blink::WebMediaDevicesRequest& request,
59 int audio_input_request_id,
60 int video_input_request_id)
61 : request(request),
62 audio_input_request_id(audio_input_request_id),
63 video_input_request_id(video_input_request_id),
64 has_audio_input_returned(false),
65 has_video_input_returned(false) {}
66
67 blink::WebMediaDevicesRequest request;
68 int audio_input_request_id;
69 int video_input_request_id;
70 bool has_audio_input_returned;
71 bool has_video_input_returned;
72 StreamDeviceInfoArray audio_input_devices;
73 StreamDeviceInfoArray video_input_devices;
74 };
75
56 MediaStreamImpl::MediaStreamImpl( 76 MediaStreamImpl::MediaStreamImpl(
57 RenderView* render_view, 77 RenderView* render_view,
58 MediaStreamDispatcher* media_stream_dispatcher, 78 MediaStreamDispatcher* media_stream_dispatcher,
59 PeerConnectionDependencyFactory* dependency_factory) 79 PeerConnectionDependencyFactory* dependency_factory)
60 : RenderViewObserver(render_view), 80 : RenderViewObserver(render_view),
61 dependency_factory_(dependency_factory), 81 dependency_factory_(dependency_factory),
62 media_stream_dispatcher_(media_stream_dispatcher) { 82 media_stream_dispatcher_(media_stream_dispatcher) {
63 } 83 }
64 84
65 MediaStreamImpl::~MediaStreamImpl() { 85 MediaStreamImpl::~MediaStreamImpl() {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 DCHECK(CalledOnValidThread()); 183 DCHECK(CalledOnValidThread());
164 UserMediaRequestInfo* request = FindUserMediaRequestInfo(user_media_request); 184 UserMediaRequestInfo* request = FindUserMediaRequestInfo(user_media_request);
165 if (request) { 185 if (request) {
166 // We can't abort the stream generation process. 186 // We can't abort the stream generation process.
167 // Instead, erase the request. Once the stream is generated we will stop the 187 // Instead, erase the request. Once the stream is generated we will stop the
168 // stream if the request does not exist. 188 // stream if the request does not exist.
169 DeleteUserMediaRequestInfo(request); 189 DeleteUserMediaRequestInfo(request);
170 } 190 }
171 } 191 }
172 192
193 void MediaStreamImpl::requestMediaDevices(
194 const blink::WebMediaDevicesRequest& media_devices_request) {
195 UpdateWebRTCMethodCount(WEBKIT_GET_MEDIA_DEVICES);
196 DCHECK(CalledOnValidThread());
197
198 int audio_input_request_id = g_next_request_id++;
199 int video_input_request_id = g_next_request_id++;
200
201 // |media_devices_request| can't be mocked, so in tests it will be empty (the
202 // underlying pointer is null). In order to use this function in a test we
203 // need to check if it isNull.
204 GURL security_origin;
205 if (!media_devices_request.isNull())
206 security_origin = GURL(media_devices_request.securityOrigin().toString());
207
208 DVLOG(1) << "MediaStreamImpl::requestMediaDevices(" << audio_input_request_id
209 << ", " << video_input_request_id << ", "
210 << security_origin.spec() << ")";
211
212 media_devices_requests_.push_back(new MediaDevicesRequestInfo(
213 media_devices_request, audio_input_request_id, video_input_request_id));
214
215 media_stream_dispatcher_->EnumerateDevices(
216 audio_input_request_id,
217 AsWeakPtr(),
218 MEDIA_DEVICE_AUDIO_CAPTURE,
219 security_origin);
220
221 media_stream_dispatcher_->EnumerateDevices(
222 video_input_request_id,
223 AsWeakPtr(),
224 MEDIA_DEVICE_VIDEO_CAPTURE,
225 security_origin);
226 }
227
228 void MediaStreamImpl::cancelMediaDevicesRequest(
229 const blink::WebMediaDevicesRequest& media_devices_request) {
230 DCHECK(CalledOnValidThread());
231 MediaDevicesRequestInfo* request =
232 FindMediaDevicesRequestInfo(media_devices_request);
233 if (!request)
234 return;
235
236 // Cancel device enumeration.
237 media_stream_dispatcher_->StopEnumerateDevices(
238 request->audio_input_request_id,
239 AsWeakPtr());
240 media_stream_dispatcher_->StopEnumerateDevices(
241 request->video_input_request_id,
242 AsWeakPtr());
243 DeleteMediaDevicesRequestInfo(request);
244 }
245
173 // Callback from MediaStreamDispatcher. 246 // Callback from MediaStreamDispatcher.
174 // The requested stream have been generated by the MediaStreamDispatcher. 247 // The requested stream have been generated by the MediaStreamDispatcher.
175 void MediaStreamImpl::OnStreamGenerated( 248 void MediaStreamImpl::OnStreamGenerated(
176 int request_id, 249 int request_id,
177 const std::string& label, 250 const std::string& label,
178 const StreamDeviceInfoArray& audio_array, 251 const StreamDeviceInfoArray& audio_array,
179 const StreamDeviceInfoArray& video_array) { 252 const StreamDeviceInfoArray& video_array) {
180 DCHECK(CalledOnValidThread()); 253 DCHECK(CalledOnValidThread());
181 DVLOG(1) << "MediaStreamImpl::OnStreamGenerated stream:" << label; 254 DVLOG(1) << "MediaStreamImpl::OnStreamGenerated stream:" << label;
182 255
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 GetUserMediaRequestSucceeded(request->web_stream, &request->request); 484 GetUserMediaRequestSucceeded(request->web_stream, &request->request);
412 else 485 else
413 GetUserMediaRequestFailed(&request->request, result); 486 GetUserMediaRequestFailed(&request->request, result);
414 487
415 DeleteUserMediaRequestInfo(request); 488 DeleteUserMediaRequestInfo(request);
416 } 489 }
417 490
418 void MediaStreamImpl::OnDevicesEnumerated( 491 void MediaStreamImpl::OnDevicesEnumerated(
419 int request_id, 492 int request_id,
420 const StreamDeviceInfoArray& device_array) { 493 const StreamDeviceInfoArray& device_array) {
421 DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" 494 DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" << request_id << ")";
422 << request_id << ")"; 495
423 NOTIMPLEMENTED(); 496 MediaDevicesRequestInfo* request = FindMediaDevicesRequestInfo(request_id);
497 DCHECK(request);
498
499 if (request_id == request->audio_input_request_id) {
500 request->has_audio_input_returned = true;
501 DCHECK(request->audio_input_devices.empty());
502 request->audio_input_devices = device_array;
503 } else {
504 DCHECK(request_id == request->video_input_request_id);
505 request->has_video_input_returned = true;
506 DCHECK(request->video_input_devices.empty());
507 request->video_input_devices = device_array;
508 }
509
510 if (!request->has_audio_input_returned ||
511 !request->has_video_input_returned) {
512 // Wait for the rest of the devices to complete.
513 return;
514 }
515
516 // Both audio and video devices are ready for copying.
517 // TODO(grunell): Add support for output devices and group id.
518 blink::WebVector<blink::WebMediaDeviceInfo>
519 devices(request->audio_input_devices.size() +
520 request->video_input_devices.size());
521 for (size_t i = 0; i < request->audio_input_devices.size(); ++i) {
522 const MediaStreamDevice& device = request->audio_input_devices[i].device;
523 DCHECK_EQ(device.type, MEDIA_DEVICE_AUDIO_CAPTURE);
524 devices[i].initialize(blink::WebString::fromUTF8(device.id),
525 blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput,
526 blink::WebString::fromUTF8(device.name),
527 blink::WebString());
528 }
529 size_t audio_size = request->audio_input_devices.size();
530 for (size_t i = 0; i < request->video_input_devices.size(); ++i) {
531 const MediaStreamDevice& device = request->video_input_devices[i].device;
532 DCHECK_EQ(device.type, MEDIA_DEVICE_VIDEO_CAPTURE);
533 devices[audio_size + i].initialize(
534 blink::WebString::fromUTF8(device.id),
535 blink::WebMediaDeviceInfo::MediaDeviceKindVideoInput,
536 blink::WebString::fromUTF8(device.name),
537 blink::WebString());
538 }
539
540 EnumerateDevicesSucceded(&request->request, devices);
541
542 // Cancel device enumeration.
543 media_stream_dispatcher_->StopEnumerateDevices(
544 request->audio_input_request_id,
545 AsWeakPtr());
546 media_stream_dispatcher_->StopEnumerateDevices(
547 request->video_input_request_id,
548 AsWeakPtr());
549
550 DeleteMediaDevicesRequestInfo(request);
424 } 551 }
425 552
426 void MediaStreamImpl::OnDeviceOpened( 553 void MediaStreamImpl::OnDeviceOpened(
427 int request_id, 554 int request_id,
428 const std::string& label, 555 const std::string& label,
429 const StreamDeviceInfo& video_device) { 556 const StreamDeviceInfo& video_device) {
430 DVLOG(1) << "MediaStreamImpl::OnDeviceOpened(" 557 DVLOG(1) << "MediaStreamImpl::OnDeviceOpened("
431 << request_id << ", " << label << ")"; 558 << request_id << ", " << label << ")";
432 NOTIMPLEMENTED(); 559 NOTIMPLEMENTED();
433 } 560 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 break; 605 break;
479 case MEDIA_DEVICE_TRACK_START_FAILURE: 606 case MEDIA_DEVICE_TRACK_START_FAILURE:
480 request_info->requestFailedUASpecific("TrackStartError"); 607 request_info->requestFailedUASpecific("TrackStartError");
481 break; 608 break;
482 default: 609 default:
483 request_info->requestFailed(); 610 request_info->requestFailed();
484 break; 611 break;
485 } 612 }
486 } 613 }
487 614
615 void MediaStreamImpl::EnumerateDevicesSucceded(
616 blink::WebMediaDevicesRequest* request,
617 blink::WebVector<blink::WebMediaDeviceInfo>& devices) {
618 request->requestSucceeded(devices);
619 }
620
488 const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource( 621 const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource(
489 const StreamDeviceInfo& device) const { 622 const StreamDeviceInfo& device) const {
490 for (LocalStreamSources::const_iterator it = local_sources_.begin(); 623 for (LocalStreamSources::const_iterator it = local_sources_.begin();
491 it != local_sources_.end(); ++it) { 624 it != local_sources_.end(); ++it) {
492 MediaStreamSource* source = 625 MediaStreamSource* source =
493 static_cast<MediaStreamSource*>(it->source.extraData()); 626 static_cast<MediaStreamSource*>(it->source.extraData());
494 const StreamDeviceInfo& active_device = source->device_info(); 627 const StreamDeviceInfo& active_device = source->device_info();
495 if (active_device.device.id == device.device.id && 628 if (active_device.device.id == device.device.id &&
496 active_device.device.type == device.device.type && 629 active_device.device.type == device.device.type &&
497 active_device.session_id == device.session_id) { 630 active_device.session_id == device.session_id) {
(...skipping 29 matching lines...) Expand all
527 UserMediaRequests::iterator it = user_media_requests_.begin(); 660 UserMediaRequests::iterator it = user_media_requests_.begin();
528 for (; it != user_media_requests_.end(); ++it) { 661 for (; it != user_media_requests_.end(); ++it) {
529 if ((*it) == request) { 662 if ((*it) == request) {
530 user_media_requests_.erase(it); 663 user_media_requests_.erase(it);
531 return; 664 return;
532 } 665 }
533 } 666 }
534 NOTREACHED(); 667 NOTREACHED();
535 } 668 }
536 669
670 MediaStreamImpl::MediaDevicesRequestInfo*
671 MediaStreamImpl::FindMediaDevicesRequestInfo(
672 int request_id) {
673 MediaDevicesRequests::iterator it = media_devices_requests_.begin();
674 for (; it != media_devices_requests_.end(); ++it) {
675 if ((*it)->audio_input_request_id == request_id ||
676 (*it)->video_input_request_id == request_id) {
677 return (*it);
678 }
679 }
680 return NULL;
681 }
682
683 MediaStreamImpl::MediaDevicesRequestInfo*
684 MediaStreamImpl::FindMediaDevicesRequestInfo(
685 const blink::WebMediaDevicesRequest& request) {
686 MediaDevicesRequests::iterator it = media_devices_requests_.begin();
687 for (; it != media_devices_requests_.end(); ++it) {
688 if ((*it)->request == request)
689 return (*it);
690 }
691 return NULL;
692 }
693
694 void MediaStreamImpl::DeleteMediaDevicesRequestInfo(
695 MediaDevicesRequestInfo* request) {
696 MediaDevicesRequests::iterator it = media_devices_requests_.begin();
697 for (; it != media_devices_requests_.end(); ++it) {
698 if ((*it) == request) {
699 media_devices_requests_.erase(it);
700 return;
701 }
702 }
703 NOTREACHED();
704 }
705
537 void MediaStreamImpl::FrameDetached(blink::WebFrame* frame) { 706 void MediaStreamImpl::FrameDetached(blink::WebFrame* frame) {
538 // Do same thing as FrameWillClose. 707 // Do same thing as FrameWillClose.
539 FrameWillClose(frame); 708 FrameWillClose(frame);
540 } 709 }
541 710
542 void MediaStreamImpl::FrameWillClose(blink::WebFrame* frame) { 711 void MediaStreamImpl::FrameWillClose(blink::WebFrame* frame) {
543 // Loop through all UserMediaRequests and find the requests that belong to the 712 // Loop through all UserMediaRequests and find the requests that belong to the
544 // frame that is being closed. 713 // frame that is being closed.
545 UserMediaRequests::iterator request_it = user_media_requests_.begin(); 714 UserMediaRequests::iterator request_it = user_media_requests_.begin();
546 while (request_it != user_media_requests_.end()) { 715 while (request_it != user_media_requests_.end()) {
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 sources_.begin(); 878 sources_.begin();
710 it != sources_.end(); ++it) { 879 it != sources_.end(); ++it) {
711 if (source.id() == it->id()) { 880 if (source.id() == it->id()) {
712 sources_.erase(it); 881 sources_.erase(it);
713 return; 882 return;
714 } 883 }
715 } 884 }
716 } 885 }
717 886
718 } // namespace content 887 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/media_stream_impl.h ('k') | content/renderer/media/media_stream_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698