| 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/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" |  | 
| 26 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 25 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 
| 27 #include "third_party/WebKit/public/web/WebDocument.h" | 26 #include "third_party/WebKit/public/web/WebDocument.h" | 
| 28 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 27 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 
| 29 | 28 | 
| 30 namespace content { | 29 namespace content { | 
| 31 namespace { | 30 namespace { | 
| 32 | 31 | 
| 33 void CopyStreamConstraints(const blink::WebMediaConstraints& constraints, | 32 void CopyStreamConstraints(const blink::WebMediaConstraints& constraints, | 
| 34                            StreamOptions::Constraints* mandatory, | 33                            StreamOptions::Constraints* mandatory, | 
| 35                            StreamOptions::Constraints* optional) { | 34                            StreamOptions::Constraints* optional) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 47     optional->push_back(StreamOptions::Constraint( | 46     optional->push_back(StreamOptions::Constraint( | 
| 48         optional_constraints[i].m_name.utf8(), | 47         optional_constraints[i].m_name.utf8(), | 
| 49         optional_constraints[i].m_value.utf8())); | 48         optional_constraints[i].m_value.utf8())); | 
| 50   } | 49   } | 
| 51 } | 50 } | 
| 52 | 51 | 
| 53 static int g_next_request_id  = 0; | 52 static int g_next_request_id  = 0; | 
| 54 | 53 | 
| 55 }  // namespace | 54 }  // namespace | 
| 56 | 55 | 
| 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 |  | 
| 76 MediaStreamImpl::MediaStreamImpl( | 56 MediaStreamImpl::MediaStreamImpl( | 
| 77     RenderView* render_view, | 57     RenderView* render_view, | 
| 78     MediaStreamDispatcher* media_stream_dispatcher, | 58     MediaStreamDispatcher* media_stream_dispatcher, | 
| 79     PeerConnectionDependencyFactory* dependency_factory) | 59     PeerConnectionDependencyFactory* dependency_factory) | 
| 80     : RenderViewObserver(render_view), | 60     : RenderViewObserver(render_view), | 
| 81       dependency_factory_(dependency_factory), | 61       dependency_factory_(dependency_factory), | 
| 82       media_stream_dispatcher_(media_stream_dispatcher) { | 62       media_stream_dispatcher_(media_stream_dispatcher) { | 
| 83 } | 63 } | 
| 84 | 64 | 
| 85 MediaStreamImpl::~MediaStreamImpl() { | 65 MediaStreamImpl::~MediaStreamImpl() { | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 183   DCHECK(CalledOnValidThread()); | 163   DCHECK(CalledOnValidThread()); | 
| 184   UserMediaRequestInfo* request = FindUserMediaRequestInfo(user_media_request); | 164   UserMediaRequestInfo* request = FindUserMediaRequestInfo(user_media_request); | 
| 185   if (request) { | 165   if (request) { | 
| 186     // We can't abort the stream generation process. | 166     // We can't abort the stream generation process. | 
| 187     // Instead, erase the request. Once the stream is generated we will stop the | 167     // Instead, erase the request. Once the stream is generated we will stop the | 
| 188     // stream if the request does not exist. | 168     // stream if the request does not exist. | 
| 189     DeleteUserMediaRequestInfo(request); | 169     DeleteUserMediaRequestInfo(request); | 
| 190   } | 170   } | 
| 191 } | 171 } | 
| 192 | 172 | 
| 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 |  | 
| 246 // Callback from MediaStreamDispatcher. | 173 // Callback from MediaStreamDispatcher. | 
| 247 // The requested stream have been generated by the MediaStreamDispatcher. | 174 // The requested stream have been generated by the MediaStreamDispatcher. | 
| 248 void MediaStreamImpl::OnStreamGenerated( | 175 void MediaStreamImpl::OnStreamGenerated( | 
| 249     int request_id, | 176     int request_id, | 
| 250     const std::string& label, | 177     const std::string& label, | 
| 251     const StreamDeviceInfoArray& audio_array, | 178     const StreamDeviceInfoArray& audio_array, | 
| 252     const StreamDeviceInfoArray& video_array) { | 179     const StreamDeviceInfoArray& video_array) { | 
| 253   DCHECK(CalledOnValidThread()); | 180   DCHECK(CalledOnValidThread()); | 
| 254   DVLOG(1) << "MediaStreamImpl::OnStreamGenerated stream:" << label; | 181   DVLOG(1) << "MediaStreamImpl::OnStreamGenerated stream:" << label; | 
| 255 | 182 | 
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 484     GetUserMediaRequestSucceeded(request->web_stream, &request->request); | 411     GetUserMediaRequestSucceeded(request->web_stream, &request->request); | 
| 485   else | 412   else | 
| 486     GetUserMediaRequestFailed(&request->request, result); | 413     GetUserMediaRequestFailed(&request->request, result); | 
| 487 | 414 | 
| 488   DeleteUserMediaRequestInfo(request); | 415   DeleteUserMediaRequestInfo(request); | 
| 489 } | 416 } | 
| 490 | 417 | 
| 491 void MediaStreamImpl::OnDevicesEnumerated( | 418 void MediaStreamImpl::OnDevicesEnumerated( | 
| 492     int request_id, | 419     int request_id, | 
| 493     const StreamDeviceInfoArray& device_array) { | 420     const StreamDeviceInfoArray& device_array) { | 
| 494   DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" << request_id << ")"; | 421   DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" | 
| 495 | 422            << request_id << ")"; | 
| 496   MediaDevicesRequestInfo* request = FindMediaDevicesRequestInfo(request_id); | 423   NOTIMPLEMENTED(); | 
| 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); |  | 
| 551 } | 424 } | 
| 552 | 425 | 
| 553 void MediaStreamImpl::OnDeviceOpened( | 426 void MediaStreamImpl::OnDeviceOpened( | 
| 554     int request_id, | 427     int request_id, | 
| 555     const std::string& label, | 428     const std::string& label, | 
| 556     const StreamDeviceInfo& video_device) { | 429     const StreamDeviceInfo& video_device) { | 
| 557   DVLOG(1) << "MediaStreamImpl::OnDeviceOpened(" | 430   DVLOG(1) << "MediaStreamImpl::OnDeviceOpened(" | 
| 558            << request_id << ", " << label << ")"; | 431            << request_id << ", " << label << ")"; | 
| 559   NOTIMPLEMENTED(); | 432   NOTIMPLEMENTED(); | 
| 560 } | 433 } | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 605       break; | 478       break; | 
| 606     case MEDIA_DEVICE_TRACK_START_FAILURE: | 479     case MEDIA_DEVICE_TRACK_START_FAILURE: | 
| 607       request_info->requestFailedUASpecific("TrackStartError"); | 480       request_info->requestFailedUASpecific("TrackStartError"); | 
| 608       break; | 481       break; | 
| 609     default: | 482     default: | 
| 610       request_info->requestFailed(); | 483       request_info->requestFailed(); | 
| 611       break; | 484       break; | 
| 612   } | 485   } | 
| 613 } | 486 } | 
| 614 | 487 | 
| 615 void MediaStreamImpl::EnumerateDevicesSucceded( |  | 
| 616     blink::WebMediaDevicesRequest* request, |  | 
| 617     blink::WebVector<blink::WebMediaDeviceInfo>& devices) { |  | 
| 618   request->requestSucceeded(devices); |  | 
| 619 } |  | 
| 620 |  | 
| 621 const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource( | 488 const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource( | 
| 622     const StreamDeviceInfo& device) const { | 489     const StreamDeviceInfo& device) const { | 
| 623   for (LocalStreamSources::const_iterator it = local_sources_.begin(); | 490   for (LocalStreamSources::const_iterator it = local_sources_.begin(); | 
| 624        it != local_sources_.end(); ++it) { | 491        it != local_sources_.end(); ++it) { | 
| 625     MediaStreamSource* source = | 492     MediaStreamSource* source = | 
| 626         static_cast<MediaStreamSource*>(it->source.extraData()); | 493         static_cast<MediaStreamSource*>(it->source.extraData()); | 
| 627     const StreamDeviceInfo& active_device = source->device_info(); | 494     const StreamDeviceInfo& active_device = source->device_info(); | 
| 628     if (active_device.device.id == device.device.id && | 495     if (active_device.device.id == device.device.id && | 
| 629         active_device.device.type == device.device.type && | 496         active_device.device.type == device.device.type && | 
| 630         active_device.session_id == device.session_id) { | 497         active_device.session_id == device.session_id) { | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 660   UserMediaRequests::iterator it = user_media_requests_.begin(); | 527   UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 661   for (; it != user_media_requests_.end(); ++it) { | 528   for (; it != user_media_requests_.end(); ++it) { | 
| 662     if ((*it) == request) { | 529     if ((*it) == request) { | 
| 663       user_media_requests_.erase(it); | 530       user_media_requests_.erase(it); | 
| 664       return; | 531       return; | 
| 665     } | 532     } | 
| 666   } | 533   } | 
| 667   NOTREACHED(); | 534   NOTREACHED(); | 
| 668 } | 535 } | 
| 669 | 536 | 
| 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 |  | 
| 706 void MediaStreamImpl::FrameDetached(blink::WebFrame* frame) { | 537 void MediaStreamImpl::FrameDetached(blink::WebFrame* frame) { | 
| 707   // Do same thing as FrameWillClose. | 538   // Do same thing as FrameWillClose. | 
| 708   FrameWillClose(frame); | 539   FrameWillClose(frame); | 
| 709 } | 540 } | 
| 710 | 541 | 
| 711 void MediaStreamImpl::FrameWillClose(blink::WebFrame* frame) { | 542 void MediaStreamImpl::FrameWillClose(blink::WebFrame* frame) { | 
| 712   // Loop through all UserMediaRequests and find the requests that belong to the | 543   // Loop through all UserMediaRequests and find the requests that belong to the | 
| 713   // frame that is being closed. | 544   // frame that is being closed. | 
| 714   UserMediaRequests::iterator request_it = user_media_requests_.begin(); | 545   UserMediaRequests::iterator request_it = user_media_requests_.begin(); | 
| 715   while (request_it != user_media_requests_.end()) { | 546   while (request_it != user_media_requests_.end()) { | 
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 878            sources_.begin(); | 709            sources_.begin(); | 
| 879        it != sources_.end(); ++it) { | 710        it != sources_.end(); ++it) { | 
| 880     if (source.id() == it->id()) { | 711     if (source.id() == it->id()) { | 
| 881       sources_.erase(it); | 712       sources_.erase(it); | 
| 882       return; | 713       return; | 
| 883     } | 714     } | 
| 884   } | 715   } | 
| 885 } | 716 } | 
| 886 | 717 | 
| 887 }  // namespace content | 718 }  // namespace content | 
| OLD | NEW | 
|---|