| 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_audio_renderer.h" | 13 #include "content/renderer/media/media_stream_audio_renderer.h" | 
|  | 14 #include "content/renderer/media/media_stream_audio_source.h" | 
| 14 #include "content/renderer/media/media_stream_dependency_factory.h" | 15 #include "content/renderer/media/media_stream_dependency_factory.h" | 
| 15 #include "content/renderer/media/media_stream_dispatcher.h" | 16 #include "content/renderer/media/media_stream_dispatcher.h" | 
| 16 #include "content/renderer/media/media_stream_extra_data.h" | 17 #include "content/renderer/media/media_stream_extra_data.h" | 
| 17 #include "content/renderer/media/media_stream_source_extra_data.h" | 18 #include "content/renderer/media/media_stream_video_capturer_source.h" | 
| 18 #include "content/renderer/media/peer_connection_tracker.h" | 19 #include "content/renderer/media/peer_connection_tracker.h" | 
| 19 #include "content/renderer/media/rtc_video_renderer.h" | 20 #include "content/renderer/media/rtc_video_renderer.h" | 
| 20 #include "content/renderer/media/webrtc_audio_capturer.h" | 21 #include "content/renderer/media/webrtc_audio_capturer.h" | 
| 21 #include "content/renderer/media/webrtc_audio_renderer.h" | 22 #include "content/renderer/media/webrtc_audio_renderer.h" | 
| 22 #include "content/renderer/media/webrtc_local_audio_renderer.h" | 23 #include "content/renderer/media/webrtc_local_audio_renderer.h" | 
| 23 #include "content/renderer/media/webrtc_logging.h" | 24 #include "content/renderer/media/webrtc_logging.h" | 
| 24 #include "content/renderer/media/webrtc_uma_histograms.h" | 25 #include "content/renderer/media/webrtc_uma_histograms.h" | 
| 25 #include "content/renderer/render_thread_impl.h" | 26 #include "content/renderer/render_thread_impl.h" | 
| 26 #include "media/base/audio_hardware_config.h" | 27 #include "media/base/audio_hardware_config.h" | 
| 27 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" | 28 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 66 | 67 | 
| 67 void GetDefaultOutputDeviceParams( | 68 void GetDefaultOutputDeviceParams( | 
| 68     int* output_sample_rate, int* output_buffer_size) { | 69     int* output_sample_rate, int* output_buffer_size) { | 
| 69   // Fetch the default audio output hardware config. | 70   // Fetch the default audio output hardware config. | 
| 70   media::AudioHardwareConfig* hardware_config = | 71   media::AudioHardwareConfig* hardware_config = | 
| 71       RenderThreadImpl::current()->GetAudioHardwareConfig(); | 72       RenderThreadImpl::current()->GetAudioHardwareConfig(); | 
| 72   *output_sample_rate = hardware_config->GetOutputSampleRate(); | 73   *output_sample_rate = hardware_config->GetOutputSampleRate(); | 
| 73   *output_buffer_size = hardware_config->GetOutputBufferSize(); | 74   *output_buffer_size = hardware_config->GetOutputBufferSize(); | 
| 74 } | 75 } | 
| 75 | 76 | 
| 76 void RemoveSource(const blink::WebMediaStreamSource& source, |  | 
| 77                   std::vector<blink::WebMediaStreamSource>* sources) { |  | 
| 78   for (std::vector<blink::WebMediaStreamSource>::iterator it = |  | 
| 79            sources->begin(); |  | 
| 80        it != sources->end(); ++it) { |  | 
| 81     if (source.id() == it->id()) { |  | 
| 82       sources->erase(it); |  | 
| 83       return; |  | 
| 84     } |  | 
| 85   } |  | 
| 86 } |  | 
| 87 |  | 
| 88 }  // namespace | 77 }  // namespace | 
| 89 | 78 | 
| 90 MediaStreamImpl::MediaStreamImpl( | 79 MediaStreamImpl::MediaStreamImpl( | 
| 91     RenderView* render_view, | 80     RenderView* render_view, | 
| 92     MediaStreamDispatcher* media_stream_dispatcher, | 81     MediaStreamDispatcher* media_stream_dispatcher, | 
| 93     MediaStreamDependencyFactory* dependency_factory) | 82     MediaStreamDependencyFactory* dependency_factory) | 
| 94     : RenderViewObserver(render_view), | 83     : RenderViewObserver(render_view), | 
| 95       dependency_factory_(dependency_factory), | 84       dependency_factory_(dependency_factory), | 
| 96       media_stream_dispatcher_(media_stream_dispatcher) { | 85       media_stream_dispatcher_(media_stream_dispatcher) { | 
| 97 } | 86 } | 
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 315          device_it != video_array.end(); ++device_it) { | 304          device_it != video_array.end(); ++device_it) { | 
| 316       if (!FindLocalSource(*device_it)) | 305       if (!FindLocalSource(*device_it)) | 
| 317         media_stream_dispatcher_->StopStreamDevice(*device_it); | 306         media_stream_dispatcher_->StopStreamDevice(*device_it); | 
| 318     } | 307     } | 
| 319 | 308 | 
| 320     DVLOG(1) << "Request ID not found"; | 309     DVLOG(1) << "Request ID not found"; | 
| 321     return; | 310     return; | 
| 322   } | 311   } | 
| 323   request_info->generated = true; | 312   request_info->generated = true; | 
| 324 | 313 | 
| 325   blink::WebVector<blink::WebMediaStreamSource> audio_source_vector( |  | 
| 326         audio_array.size()); |  | 
| 327 |  | 
| 328   // Log the device names for this request. |  | 
| 329   for (StreamDeviceInfoArray::const_iterator it = audio_array.begin(); |  | 
| 330        it != audio_array.end(); ++it) { |  | 
| 331     WebRtcLogMessage(base::StringPrintf( |  | 
| 332         "Generated media stream for request id %d contains audio device name" |  | 
| 333         " \"%s\"", |  | 
| 334         request_id, |  | 
| 335         it->device.name.c_str())); |  | 
| 336   } |  | 
| 337 |  | 
| 338   StreamDeviceInfoArray overridden_audio_array = audio_array; |  | 
| 339   if (!request_info->enable_automatic_output_device_selection) { |  | 
| 340     // If the GetUserMedia request did not explicitly set the constraint |  | 
| 341     // kMediaStreamRenderToAssociatedSink, the output device parameters must |  | 
| 342     // be removed. |  | 
| 343     for (StreamDeviceInfoArray::iterator it = overridden_audio_array.begin(); |  | 
| 344          it != overridden_audio_array.end(); ++it) { |  | 
| 345       it->device.matched_output_device_id = ""; |  | 
| 346       it->device.matched_output = MediaStreamDevice::AudioDeviceParameters(); |  | 
| 347     } |  | 
| 348   } |  | 
| 349   CreateWebKitSourceVector(label, overridden_audio_array, |  | 
| 350                            blink::WebMediaStreamSource::TypeAudio, |  | 
| 351                            request_info->frame, |  | 
| 352                            audio_source_vector); |  | 
| 353 |  | 
| 354   blink::WebVector<blink::WebMediaStreamSource> video_source_vector( |  | 
| 355       video_array.size()); |  | 
| 356   CreateWebKitSourceVector(label, video_array, |  | 
| 357                            blink::WebMediaStreamSource::TypeVideo, |  | 
| 358                            request_info->frame, |  | 
| 359                            video_source_vector); |  | 
| 360   blink::WebUserMediaRequest* request = &(request_info->request); |  | 
| 361   blink::WebString webkit_id = base::UTF8ToUTF16(label); |  | 
| 362   blink::WebMediaStream* web_stream = &(request_info->web_stream); |  | 
| 363 |  | 
| 364   blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector( |  | 
| 365       audio_array.size()); |  | 
| 366   for (size_t i = 0; i < audio_track_vector.size(); ++i) { |  | 
| 367     audio_track_vector[i].initialize(audio_source_vector[i]); |  | 
| 368     request_info->sources.push_back(audio_source_vector[i]); |  | 
| 369   } |  | 
| 370 |  | 
| 371   blink::WebVector<blink::WebMediaStreamTrack> video_track_vector( |  | 
| 372       video_array.size()); |  | 
| 373   for (size_t i = 0; i < video_track_vector.size(); ++i) { |  | 
| 374     video_track_vector[i].initialize(video_source_vector[i]); |  | 
| 375     request_info->sources.push_back(video_source_vector[i]); |  | 
| 376   } |  | 
| 377 |  | 
| 378   web_stream->initialize(webkit_id, audio_track_vector, |  | 
| 379                          video_track_vector); |  | 
| 380 |  | 
| 381   // WebUserMediaRequest don't have an implementation in unit tests. | 314   // WebUserMediaRequest don't have an implementation in unit tests. | 
| 382   // Therefore we need to check for isNull here. | 315   // Therefore we need to check for isNull here. | 
|  | 316   blink::WebUserMediaRequest* request = &(request_info->request); | 
| 383   blink::WebMediaConstraints audio_constraints = request->isNull() ? | 317   blink::WebMediaConstraints audio_constraints = request->isNull() ? | 
| 384       blink::WebMediaConstraints() : request->audioConstraints(); | 318       blink::WebMediaConstraints() : request->audioConstraints(); | 
| 385   blink::WebMediaConstraints video_constraints = request->isNull() ? | 319   blink::WebMediaConstraints video_constraints = request->isNull() ? | 
| 386       blink::WebMediaConstraints() : request->videoConstraints(); | 320       blink::WebMediaConstraints() : request->videoConstraints(); | 
| 387 | 321 | 
| 388   dependency_factory_->CreateNativeMediaSources( | 322   blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector( | 
| 389       RenderViewObserver::routing_id(), | 323       audio_array.size()); | 
| 390       audio_constraints, video_constraints, web_stream, | 324   CreateAudioTracks(audio_array, audio_constraints, &audio_track_vector, | 
| 391       base::Bind(&MediaStreamImpl::OnCreateNativeSourcesComplete, AsWeakPtr())); | 325                     request_info); | 
|  | 326 | 
|  | 327   blink::WebVector<blink::WebMediaStreamTrack> video_track_vector( | 
|  | 328       video_array.size()); | 
|  | 329   CreateVideoTracks(video_array, video_constraints, &video_track_vector, | 
|  | 330                     request_info); | 
|  | 331 | 
|  | 332   blink::WebString webkit_id = base::UTF8ToUTF16(label); | 
|  | 333   blink::WebMediaStream* web_stream = &(request_info->web_stream); | 
|  | 334 | 
|  | 335   web_stream->initialize(webkit_id, audio_track_vector, | 
|  | 336                          video_track_vector); | 
|  | 337 | 
|  | 338   // Wait for the tracks to be started successfully or to fail. | 
|  | 339   request_info->CallbackOnTracksStarted( | 
|  | 340       base::Bind(&MediaStreamImpl::OnCreateNativeTracksCompleted, AsWeakPtr())); | 
| 392 } | 341 } | 
| 393 | 342 | 
| 394 // Callback from MediaStreamDispatcher. | 343 // Callback from MediaStreamDispatcher. | 
| 395 // The requested stream failed to be generated. | 344 // The requested stream failed to be generated. | 
| 396 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { | 345 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { | 
| 397   DCHECK(CalledOnValidThread()); | 346   DCHECK(CalledOnValidThread()); | 
| 398   DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" | 347   DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" | 
| 399            << request_id << ")"; | 348            << request_id << ")"; | 
| 400   UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id); | 349   UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id); | 
| 401   if (!request_info) { | 350   if (!request_info) { | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 437       local_sources_.erase(device_it); | 386       local_sources_.erase(device_it); | 
| 438       break; | 387       break; | 
| 439     } | 388     } | 
| 440   } | 389   } | 
| 441 | 390 | 
| 442   // Remove the reference to this source from all |user_media_requests_|. | 391   // Remove the reference to this source from all |user_media_requests_|. | 
| 443   // TODO(perkj): The below is not necessary once we don't need to support | 392   // TODO(perkj): The below is not necessary once we don't need to support | 
| 444   // MediaStream::Stop(). | 393   // MediaStream::Stop(). | 
| 445   UserMediaRequests::iterator it = user_media_requests_.begin(); | 394   UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 446   while (it != user_media_requests_.end()) { | 395   while (it != user_media_requests_.end()) { | 
| 447     RemoveSource(source, &(*it)->sources); | 396     (*it)->RemoveSource(source); | 
| 448     if ((*it)->sources.empty()) { | 397     if ((*it)->AreAllSourcesRemoved()) { | 
| 449       it = user_media_requests_.erase(it); | 398       it = user_media_requests_.erase(it); | 
| 450     } else { | 399     } else { | 
| 451       ++it; | 400       ++it; | 
| 452     } | 401     } | 
| 453   } | 402   } | 
| 454 } | 403 } | 
| 455 | 404 | 
| 456 void MediaStreamImpl::CreateWebKitSourceVector( | 405 void MediaStreamImpl::InitializeSourceObject( | 
| 457     const std::string& label, | 406     const StreamDeviceInfo& device, | 
|  | 407     blink::WebMediaStreamSource::Type type, | 
|  | 408     const blink::WebMediaConstraints& constraints, | 
|  | 409     blink::WebFrame* frame, | 
|  | 410     blink::WebMediaStreamSource* webkit_source) { | 
|  | 411   const blink::WebMediaStreamSource* existing_source = | 
|  | 412       FindLocalSource(device); | 
|  | 413   if (existing_source) { | 
|  | 414     *webkit_source = *existing_source; | 
|  | 415     DVLOG(1) << "Source already exist. Reusing source with id " | 
|  | 416              << webkit_source->id().utf8(); | 
|  | 417     return; | 
|  | 418   } | 
|  | 419 | 
|  | 420   webkit_source->initialize( | 
|  | 421       base::UTF8ToUTF16(device.device.id), | 
|  | 422       type, | 
|  | 423       base::UTF8ToUTF16(device.device.name)); | 
|  | 424 | 
|  | 425   DVLOG(1) << "Initialize source object :" | 
|  | 426            << "id = " << webkit_source->id().utf8() | 
|  | 427            << ", name = " << webkit_source->name().utf8(); | 
|  | 428 | 
|  | 429   if (type == blink::WebMediaStreamSource::TypeVideo) { | 
|  | 430     MediaStreamVideoCapturerSource* video_source( | 
|  | 431         new content::MediaStreamVideoCapturerSource( | 
|  | 432             device, | 
|  | 433             base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr()), | 
|  | 434             dependency_factory_)); | 
|  | 435     webkit_source->setExtraData(video_source); | 
|  | 436   } else { | 
|  | 437     DCHECK_EQ(blink::WebMediaStreamSource::TypeAudio, type); | 
|  | 438     MediaStreamAudioSource* audio_source( | 
|  | 439         new MediaStreamAudioSource( | 
|  | 440             RenderViewObserver::routing_id(), | 
|  | 441             device, | 
|  | 442             base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr()), | 
|  | 443             dependency_factory_)); | 
|  | 444     webkit_source->setExtraData(audio_source); | 
|  | 445   } | 
|  | 446   local_sources_.push_back(LocalStreamSource(frame, *webkit_source)); | 
|  | 447 } | 
|  | 448 | 
|  | 449 void MediaStreamImpl::CreateVideoTracks( | 
| 458     const StreamDeviceInfoArray& devices, | 450     const StreamDeviceInfoArray& devices, | 
| 459     blink::WebMediaStreamSource::Type type, | 451     const blink::WebMediaConstraints& constraints, | 
| 460     blink::WebFrame* frame, | 452     blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, | 
| 461     blink::WebVector<blink::WebMediaStreamSource>& webkit_sources) { | 453     UserMediaRequestInfo* request) { | 
| 462   CHECK_EQ(devices.size(), webkit_sources.size()); | 454   DCHECK_EQ(devices.size(), webkit_tracks->size()); | 
|  | 455 | 
| 463   for (size_t i = 0; i < devices.size(); ++i) { | 456   for (size_t i = 0; i < devices.size(); ++i) { | 
| 464     const blink::WebMediaStreamSource* existing_source = | 457     blink::WebMediaStreamSource webkit_source; | 
| 465         FindLocalSource(devices[i]); | 458     InitializeSourceObject(devices[i], | 
| 466     if (existing_source) { | 459                            blink::WebMediaStreamSource::TypeVideo, | 
| 467       webkit_sources[i] = *existing_source; | 460                            constraints, | 
| 468       DVLOG(1) << "Source already exist. Reusing source with id " | 461                            request->frame, | 
| 469                << webkit_sources[i]. id().utf8(); | 462                            &webkit_source); | 
| 470       continue; | 463     (*webkit_tracks)[i].initialize(webkit_source); | 
| 471     } | 464     request->StartTrack((*webkit_tracks)[i], constraints); | 
| 472     webkit_sources[i].initialize( |  | 
| 473         base::UTF8ToUTF16(devices[i].device.id), |  | 
| 474         type, |  | 
| 475         base::UTF8ToUTF16(devices[i].device.name)); |  | 
| 476     MediaStreamSourceExtraData* source_extra_data( |  | 
| 477         new content::MediaStreamSourceExtraData( |  | 
| 478             devices[i], |  | 
| 479             base::Bind(&MediaStreamImpl::OnLocalSourceStop, AsWeakPtr()))); |  | 
| 480     // |source_extra_data| is owned by webkit_sources[i]. |  | 
| 481     webkit_sources[i].setExtraData(source_extra_data); |  | 
| 482     local_sources_.push_back(LocalStreamSource(frame, webkit_sources[i])); |  | 
| 483   } | 465   } | 
| 484 } | 466 } | 
| 485 | 467 | 
| 486 // Callback from MediaStreamDependencyFactory when the sources in |web_stream| | 468 void MediaStreamImpl::CreateAudioTracks( | 
| 487 // have been generated. | 469     const StreamDeviceInfoArray& devices, | 
| 488 void MediaStreamImpl::OnCreateNativeSourcesComplete( | 470     const blink::WebMediaConstraints& constraints, | 
| 489     blink::WebMediaStream* web_stream, | 471     blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, | 
| 490     bool request_succeeded) { | 472     UserMediaRequestInfo* request) { | 
| 491   UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(web_stream); | 473   DCHECK_EQ(devices.size(), webkit_tracks->size()); | 
| 492   if (!request_info) { | 474 | 
| 493     // This can happen if the request is canceled or the frame reloads while | 475   // Log the device names for this request. | 
| 494     // MediaStreamDependencyFactory is creating the sources. | 476   for (StreamDeviceInfoArray::const_iterator it = devices.begin(); | 
| 495     DVLOG(1) << "Request ID not found"; | 477        it != devices.end(); ++it) { | 
| 496     return; | 478     WebRtcLogMessage(base::StringPrintf( | 
|  | 479         "Generated media stream for request id %d contains audio device name" | 
|  | 480         " \"%s\"", | 
|  | 481         request->request_id, | 
|  | 482         it->device.name.c_str())); | 
| 497   } | 483   } | 
| 498 | 484 | 
|  | 485   StreamDeviceInfoArray overridden_audio_array = devices; | 
|  | 486   if (!request->enable_automatic_output_device_selection) { | 
|  | 487     // If the GetUserMedia request did not explicitly set the constraint | 
|  | 488     // kMediaStreamRenderToAssociatedSink, the output device parameters must | 
|  | 489     // be removed. | 
|  | 490     for (StreamDeviceInfoArray::iterator it = overridden_audio_array.begin(); | 
|  | 491          it != overridden_audio_array.end(); ++it) { | 
|  | 492       it->device.matched_output_device_id = ""; | 
|  | 493       it->device.matched_output = MediaStreamDevice::AudioDeviceParameters(); | 
|  | 494     } | 
|  | 495   } | 
|  | 496 | 
|  | 497   for (size_t i = 0; i < overridden_audio_array.size(); ++i) { | 
|  | 498     blink::WebMediaStreamSource webkit_source; | 
|  | 499     InitializeSourceObject(overridden_audio_array[i], | 
|  | 500                            blink::WebMediaStreamSource::TypeAudio, | 
|  | 501                            constraints, | 
|  | 502                            request->frame, | 
|  | 503                            &webkit_source); | 
|  | 504     (*webkit_tracks)[i].initialize(webkit_source); | 
|  | 505     request->StartTrack((*webkit_tracks)[i], constraints); | 
|  | 506   } | 
|  | 507 } | 
|  | 508 | 
|  | 509 void MediaStreamImpl::OnCreateNativeTracksCompleted( | 
|  | 510     UserMediaRequestInfo* request, | 
|  | 511     bool request_succeeded) { | 
| 499   // Create a native representation of the stream. | 512   // Create a native representation of the stream. | 
| 500   if (request_succeeded) { | 513   if (request_succeeded) { | 
| 501     dependency_factory_->CreateNativeLocalMediaStream( | 514     dependency_factory_->CreateNativeLocalMediaStream( | 
| 502         web_stream, | 515         &request->web_stream, | 
| 503         base::Bind(&MediaStreamImpl::OnLocalMediaStreamStop, AsWeakPtr())); | 516         base::Bind(&MediaStreamImpl::OnLocalMediaStreamStop, AsWeakPtr())); | 
| 504   } | 517   } | 
| 505   DVLOG(1) << "MediaStreamImpl::OnCreateNativeSourcesComplete(" | 518   DVLOG(1) << "MediaStreamImpl::OnCreateNativeTracksComplete(" | 
| 506            << "{request_id = " << request_info->request_id << "} " | 519            << "{request_id = " << request->request_id << "} " | 
| 507            << "{request_succeeded = " << request_succeeded << "})"; | 520            << "{request_succeeded = " << request_succeeded << "})"; | 
| 508   CompleteGetUserMediaRequest(request_info->web_stream, &request_info->request, | 521   CompleteGetUserMediaRequest(request->web_stream, &request->request, | 
| 509                               request_succeeded); | 522                               request_succeeded); | 
| 510   if (!request_succeeded) { | 523   if (!request_succeeded) { | 
| 511     // TODO(perkj): Once we don't support MediaStream::Stop the |request_info| | 524     // TODO(perkj): Once we don't support MediaStream::Stop the |request_info| | 
| 512     // can be deleted even if the request succeeds. | 525     // can be deleted even if the request succeeds. | 
| 513     DeleteUserMediaRequestInfo(request_info); | 526     DeleteUserMediaRequestInfo(request); | 
| 514     StopUnreferencedSources(true); | 527     StopUnreferencedSources(true); | 
| 515   } | 528   } | 
| 516 } | 529 } | 
| 517 | 530 | 
| 518 void MediaStreamImpl::OnDevicesEnumerated( | 531 void MediaStreamImpl::OnDevicesEnumerated( | 
| 519     int request_id, | 532     int request_id, | 
| 520     const StreamDeviceInfoArray& device_array) { | 533     const StreamDeviceInfoArray& device_array) { | 
| 521   DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" | 534   DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" | 
| 522            << request_id << ")"; | 535            << request_id << ")"; | 
| 523   NOTIMPLEMENTED(); | 536   NOTIMPLEMENTED(); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 546     request_info->requestSucceeded(stream); | 559     request_info->requestSucceeded(stream); | 
| 547   } else { | 560   } else { | 
| 548     request_info->requestFailed(); | 561     request_info->requestFailed(); | 
| 549   } | 562   } | 
| 550 } | 563 } | 
| 551 | 564 | 
| 552 const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource( | 565 const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource( | 
| 553     const StreamDeviceInfo& device) const { | 566     const StreamDeviceInfo& device) const { | 
| 554   for (LocalStreamSources::const_iterator it = local_sources_.begin(); | 567   for (LocalStreamSources::const_iterator it = local_sources_.begin(); | 
| 555        it != local_sources_.end(); ++it) { | 568        it != local_sources_.end(); ++it) { | 
| 556     MediaStreamSourceExtraData* extra_data = | 569     MediaStreamSource* source = | 
| 557         static_cast<MediaStreamSourceExtraData*>( | 570         static_cast<MediaStreamSource*>(it->source.extraData()); | 
| 558             it->source.extraData()); | 571     const StreamDeviceInfo& active_device = source->device_info(); | 
| 559     const StreamDeviceInfo& active_device = extra_data->device_info(); |  | 
| 560     if (active_device.device.id == device.device.id && | 572     if (active_device.device.id == device.device.id && | 
| 561         active_device.device.type == device.device.type && | 573         active_device.device.type == device.device.type && | 
| 562         active_device.session_id == device.session_id) { | 574         active_device.session_id == device.session_id) { | 
| 563       return &it->source; | 575       return &it->source; | 
| 564     } | 576     } | 
| 565   } | 577   } | 
| 566   return NULL; | 578   return NULL; | 
| 567 } | 579 } | 
| 568 | 580 | 
| 569 bool MediaStreamImpl::FindSourceInRequests( | 581 bool MediaStreamImpl::IsSourceInRequests( | 
| 570     const blink::WebMediaStreamSource& source) const { | 582     const blink::WebMediaStreamSource& source) const { | 
| 571   for (UserMediaRequests::const_iterator req_it = user_media_requests_.begin(); | 583   for (UserMediaRequests::const_iterator req_it = user_media_requests_.begin(); | 
| 572        req_it != user_media_requests_.end(); ++req_it) { | 584        req_it != user_media_requests_.end(); ++req_it) { | 
| 573     const std::vector<blink::WebMediaStreamSource>& sources = | 585     if ((*req_it)->IsSourceUsed(source)) | 
| 574         (*req_it)->sources; | 586       return true; | 
| 575     for (std::vector<blink::WebMediaStreamSource>::const_iterator source_it = |  | 
| 576              sources.begin(); |  | 
| 577          source_it != sources.end(); ++source_it) { |  | 
| 578       if (source_it->id() == source.id()) { |  | 
| 579         return true; |  | 
| 580       } |  | 
| 581     } |  | 
| 582   } | 587   } | 
| 583   return false; | 588   return false; | 
| 584 } | 589 } | 
| 585 | 590 | 
| 586 MediaStreamImpl::UserMediaRequestInfo* | 591 MediaStreamImpl::UserMediaRequestInfo* | 
| 587 MediaStreamImpl::FindUserMediaRequestInfo(int request_id) { | 592 MediaStreamImpl::FindUserMediaRequestInfo(int request_id) { | 
| 588   UserMediaRequests::iterator it = user_media_requests_.begin(); | 593   UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 589   for (; it != user_media_requests_.end(); ++it) { | 594   for (; it != user_media_requests_.end(); ++it) { | 
| 590     if ((*it)->request_id == request_id) | 595     if ((*it)->request_id == request_id) | 
| 591       return (*it); | 596       return (*it); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 607 MediaStreamImpl::UserMediaRequestInfo* | 612 MediaStreamImpl::UserMediaRequestInfo* | 
| 608 MediaStreamImpl::FindUserMediaRequestInfo(const std::string& label) { | 613 MediaStreamImpl::FindUserMediaRequestInfo(const std::string& label) { | 
| 609   UserMediaRequests::iterator it = user_media_requests_.begin(); | 614   UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 610   for (; it != user_media_requests_.end(); ++it) { | 615   for (; it != user_media_requests_.end(); ++it) { | 
| 611     if ((*it)->generated && (*it)->web_stream.id() == base::UTF8ToUTF16(label)) | 616     if ((*it)->generated && (*it)->web_stream.id() == base::UTF8ToUTF16(label)) | 
| 612       return (*it); | 617       return (*it); | 
| 613   } | 618   } | 
| 614   return NULL; | 619   return NULL; | 
| 615 } | 620 } | 
| 616 | 621 | 
| 617 MediaStreamImpl::UserMediaRequestInfo* |  | 
| 618 MediaStreamImpl::FindUserMediaRequestInfo( |  | 
| 619     blink::WebMediaStream* web_stream) { |  | 
| 620   UserMediaRequests::iterator it = user_media_requests_.begin(); |  | 
| 621   for (; it != user_media_requests_.end(); ++it) { |  | 
| 622     if (&((*it)->web_stream) == web_stream) |  | 
| 623       return  (*it); |  | 
| 624   } |  | 
| 625   return NULL; |  | 
| 626 } |  | 
| 627 |  | 
| 628 void MediaStreamImpl::DeleteUserMediaRequestInfo( | 622 void MediaStreamImpl::DeleteUserMediaRequestInfo( | 
| 629     UserMediaRequestInfo* request) { | 623     UserMediaRequestInfo* request) { | 
| 630   UserMediaRequests::iterator it = user_media_requests_.begin(); | 624   UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 631   for (; it != user_media_requests_.end(); ++it) { | 625   for (; it != user_media_requests_.end(); ++it) { | 
| 632     if ((*it) == request) { | 626     if ((*it) == request) { | 
| 633       user_media_requests_.erase(it); | 627       user_media_requests_.erase(it); | 
| 634       return; | 628       return; | 
| 635     } | 629     } | 
| 636   } | 630   } | 
| 637   NOTREACHED(); | 631   NOTREACHED(); | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 681     const std::string& label) { | 675     const std::string& label) { | 
| 682   DVLOG(1) << "MediaStreamImpl::OnLocalMediaStreamStop(" << label << ")"; | 676   DVLOG(1) << "MediaStreamImpl::OnLocalMediaStreamStop(" << label << ")"; | 
| 683 | 677 | 
| 684   UserMediaRequestInfo* user_media_request = FindUserMediaRequestInfo(label); | 678   UserMediaRequestInfo* user_media_request = FindUserMediaRequestInfo(label); | 
| 685   if (user_media_request) { | 679   if (user_media_request) { | 
| 686     DeleteUserMediaRequestInfo(user_media_request); | 680     DeleteUserMediaRequestInfo(user_media_request); | 
| 687   } | 681   } | 
| 688   StopUnreferencedSources(true); | 682   StopUnreferencedSources(true); | 
| 689 } | 683 } | 
| 690 | 684 | 
| 691 void MediaStreamImpl::OnLocalSourceStop( | 685 void MediaStreamImpl::OnLocalSourceStopped( | 
| 692     const blink::WebMediaStreamSource& source) { | 686     const blink::WebMediaStreamSource& source) { | 
| 693   DCHECK(CalledOnValidThread()); | 687   DCHECK(CalledOnValidThread()); | 
| 694 | 688 | 
| 695   StopLocalSource(source, true); |  | 
| 696 |  | 
| 697   bool device_found = false; | 689   bool device_found = false; | 
| 698   for (LocalStreamSources::iterator device_it = local_sources_.begin(); | 690   for (LocalStreamSources::iterator device_it = local_sources_.begin(); | 
| 699        device_it != local_sources_.end(); ++device_it) { | 691        device_it != local_sources_.end(); ++device_it) { | 
| 700     if (device_it->source.id()  == source.id()) { | 692     if (device_it->source.id()  == source.id()) { | 
| 701       device_found = true; | 693       device_found = true; | 
| 702       local_sources_.erase(device_it); | 694       local_sources_.erase(device_it); | 
| 703       break; | 695       break; | 
| 704     } | 696     } | 
| 705   } | 697   } | 
| 706   CHECK(device_found); | 698   CHECK(device_found); | 
| 707 | 699 | 
| 708   // Remove the reference to this source from all |user_media_requests_|. | 700   // Remove the reference to this source from all |user_media_requests_|. | 
| 709   // TODO(perkj): The below is not necessary once we don't need to support | 701   // TODO(perkj): The below is not necessary once we don't need to support | 
| 710   // MediaStream::Stop(). | 702   // MediaStream::Stop(). | 
| 711   UserMediaRequests::iterator it = user_media_requests_.begin(); | 703   UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 712   while (it != user_media_requests_.end()) { | 704   while (it != user_media_requests_.end()) { | 
| 713     RemoveSource(source, &(*it)->sources); | 705     (*it)->RemoveSource(source); | 
| 714     if ((*it)->sources.empty()) { | 706     if ((*it)->AreAllSourcesRemoved()) { | 
| 715       it = user_media_requests_.erase(it); | 707       it = user_media_requests_.erase(it); | 
| 716     } else { | 708     } else { | 
| 717       ++it; | 709       ++it; | 
| 718     } | 710     } | 
| 719   } | 711   } | 
|  | 712 | 
|  | 713   MediaStreamSource* source_impl = | 
|  | 714       static_cast<MediaStreamSource*> (source.extraData()); | 
|  | 715   media_stream_dispatcher_->StopStreamDevice(source_impl->device_info()); | 
| 720 } | 716 } | 
| 721 | 717 | 
| 722 void MediaStreamImpl::StopLocalSource( | 718 void MediaStreamImpl::StopLocalSource( | 
| 723     const blink::WebMediaStreamSource& source, | 719     const blink::WebMediaStreamSource& source, | 
| 724     bool notify_dispatcher) { | 720     bool notify_dispatcher) { | 
| 725   MediaStreamSourceExtraData* extra_data = | 721   MediaStreamSource* source_impl = | 
| 726         static_cast<MediaStreamSourceExtraData*> (source.extraData()); | 722       static_cast<MediaStreamSource*> (source.extraData()); | 
| 727   CHECK(extra_data); |  | 
| 728   DVLOG(1) << "MediaStreamImpl::StopLocalSource(" | 723   DVLOG(1) << "MediaStreamImpl::StopLocalSource(" | 
| 729            << "{device_id = " << extra_data->device_info().device.id << "})"; | 724            << "{device_id = " << source_impl->device_info().device.id << "})"; | 
| 730 |  | 
| 731   if (source.type() == blink::WebMediaStreamSource::TypeAudio) { |  | 
| 732     if (extra_data->GetAudioCapturer()) |  | 
| 733       extra_data->GetAudioCapturer()->Stop(); |  | 
| 734   } |  | 
| 735 | 725 | 
| 736   if (notify_dispatcher) | 726   if (notify_dispatcher) | 
| 737     media_stream_dispatcher_->StopStreamDevice(extra_data->device_info()); | 727     media_stream_dispatcher_->StopStreamDevice(source_impl->device_info()); | 
| 738 | 728 | 
| 739   blink::WebMediaStreamSource writable_source(source); | 729   source_impl->ResetSourceStoppedCallback(); | 
| 740   writable_source.setReadyState( | 730   source_impl->StopSource(); | 
| 741       blink::WebMediaStreamSource::ReadyStateEnded); |  | 
| 742   writable_source.setExtraData(NULL); |  | 
| 743 } | 731 } | 
| 744 | 732 | 
| 745 void MediaStreamImpl::StopUnreferencedSources(bool notify_dispatcher) { | 733 void MediaStreamImpl::StopUnreferencedSources(bool notify_dispatcher) { | 
| 746   LocalStreamSources::iterator source_it = local_sources_.begin(); | 734   LocalStreamSources::iterator source_it = local_sources_.begin(); | 
| 747   while (source_it != local_sources_.end()) { | 735   while (source_it != local_sources_.end()) { | 
| 748     if (!FindSourceInRequests(source_it->source)) { | 736     if (!IsSourceInRequests(source_it->source)) { | 
| 749       StopLocalSource(source_it->source, notify_dispatcher); | 737       StopLocalSource(source_it->source, notify_dispatcher); | 
| 750       source_it = local_sources_.erase(source_it); | 738       source_it = local_sources_.erase(source_it); | 
| 751     } else { | 739     } else { | 
| 752       ++source_it; | 740       ++source_it; | 
| 753     } | 741     } | 
| 754   } | 742   } | 
| 755 } | 743 } | 
| 756 | 744 | 
| 757 scoped_refptr<WebRtcAudioRenderer> MediaStreamImpl::CreateRemoteAudioRenderer( | 745 scoped_refptr<WebRtcAudioRenderer> MediaStreamImpl::CreateRemoteAudioRenderer( | 
| 758     webrtc::MediaStreamInterface* stream, | 746     webrtc::MediaStreamInterface* stream, | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 807   DCHECK(CalledOnValidThread()); | 795   DCHECK(CalledOnValidThread()); | 
| 808   WebRtcAudioDeviceImpl* audio_device = | 796   WebRtcAudioDeviceImpl* audio_device = | 
| 809       dependency_factory_->GetWebRtcAudioDevice(); | 797       dependency_factory_->GetWebRtcAudioDevice(); | 
| 810   if (!audio_device) | 798   if (!audio_device) | 
| 811     return false; | 799     return false; | 
| 812 | 800 | 
| 813   return audio_device->GetAuthorizedDeviceInfoForAudioRenderer( | 801   return audio_device->GetAuthorizedDeviceInfoForAudioRenderer( | 
| 814       session_id, output_sample_rate, output_frames_per_buffer); | 802       session_id, output_sample_rate, output_frames_per_buffer); | 
| 815 } | 803 } | 
| 816 | 804 | 
| 817 MediaStreamSourceExtraData::MediaStreamSourceExtraData( |  | 
| 818     const StreamDeviceInfo& device_info, |  | 
| 819     const SourceStopCallback& stop_callback) |  | 
| 820     : device_info_(device_info), |  | 
| 821       stop_callback_(stop_callback) { |  | 
| 822 } |  | 
| 823 |  | 
| 824 MediaStreamSourceExtraData::MediaStreamSourceExtraData() { |  | 
| 825 } |  | 
| 826 |  | 
| 827 MediaStreamSourceExtraData::~MediaStreamSourceExtraData() {} |  | 
| 828 |  | 
| 829 void MediaStreamSourceExtraData::OnLocalSourceStop() { |  | 
| 830   if (!stop_callback_.is_null()) |  | 
| 831     stop_callback_.Run(owner()); |  | 
| 832 } |  | 
| 833 |  | 
| 834 MediaStreamExtraData::MediaStreamExtraData( | 805 MediaStreamExtraData::MediaStreamExtraData( | 
| 835     webrtc::MediaStreamInterface* stream, bool is_local) | 806     webrtc::MediaStreamInterface* stream, bool is_local) | 
| 836     : stream_(stream), | 807     : stream_(stream), | 
| 837       is_local_(is_local) { | 808       is_local_(is_local) { | 
| 838 } | 809 } | 
| 839 | 810 | 
| 840 MediaStreamExtraData::~MediaStreamExtraData() { | 811 MediaStreamExtraData::~MediaStreamExtraData() { | 
| 841 } | 812 } | 
| 842 | 813 | 
| 843 void MediaStreamExtraData::SetLocalStreamStopCallback( | 814 void MediaStreamExtraData::SetLocalStreamStopCallback( | 
| 844     const StreamStopCallback& stop_callback) { | 815     const StreamStopCallback& stop_callback) { | 
| 845   stream_stop_callback_ = stop_callback; | 816   stream_stop_callback_ = stop_callback; | 
| 846 } | 817 } | 
| 847 | 818 | 
| 848 void MediaStreamExtraData::OnLocalStreamStop() { | 819 void MediaStreamExtraData::OnLocalStreamStop() { | 
| 849   if (!stream_stop_callback_.is_null()) | 820   if (!stream_stop_callback_.is_null()) | 
| 850     stream_stop_callback_.Run(stream_->label()); | 821     stream_stop_callback_.Run(stream_->label()); | 
| 851 } | 822 } | 
| 852 | 823 | 
| 853 MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo( | 824 MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo( | 
| 854     int request_id, | 825     int request_id, | 
| 855     blink::WebFrame* frame, | 826     blink::WebFrame* frame, | 
| 856     const blink::WebUserMediaRequest& request, | 827     const blink::WebUserMediaRequest& request, | 
| 857     bool enable_automatic_output_device_selection) | 828     bool enable_automatic_output_device_selection) | 
| 858     : request_id(request_id), | 829     : request_id(request_id), | 
| 859       generated(false), | 830       generated(false), | 
| 860       enable_automatic_output_device_selection( | 831       enable_automatic_output_device_selection( | 
| 861           enable_automatic_output_device_selection), | 832           enable_automatic_output_device_selection), | 
| 862       frame(frame), | 833       frame(frame), | 
| 863       request(request) { | 834       request(request), | 
|  | 835       request_failed_(false) { | 
| 864 } | 836 } | 
| 865 | 837 | 
| 866 MediaStreamImpl::UserMediaRequestInfo::~UserMediaRequestInfo() { | 838 MediaStreamImpl::UserMediaRequestInfo::~UserMediaRequestInfo() { | 
|  | 839   DVLOG(1) << "~UserMediaRequestInfo"; | 
|  | 840 } | 
|  | 841 | 
|  | 842 void MediaStreamImpl::UserMediaRequestInfo::StartTrack( | 
|  | 843     const blink::WebMediaStreamTrack& track, | 
|  | 844     const blink::WebMediaConstraints& constraints) { | 
|  | 845   MediaStreamSource* native_source = | 
|  | 846       static_cast <MediaStreamSource*>(track.source().extraData()); | 
|  | 847   DCHECK(native_source); | 
|  | 848 | 
|  | 849   sources_.push_back(track.source()); | 
|  | 850   sources_waiting_for_callback_.push_back(native_source); | 
|  | 851   native_source->AddTrack( | 
|  | 852       track, constraints, base::Bind( | 
|  | 853           &MediaStreamImpl::UserMediaRequestInfo::OnTrackStarted, | 
|  | 854           AsWeakPtr())); | 
|  | 855 } | 
|  | 856 | 
|  | 857 void MediaStreamImpl::UserMediaRequestInfo::CallbackOnTracksStarted( | 
|  | 858     const ResourcesReady& callback) { | 
|  | 859   DCHECK(ready_callback_.is_null()); | 
|  | 860   ready_callback_ = callback; | 
|  | 861   CheckAllTracksStarted(); | 
|  | 862 } | 
|  | 863 | 
|  | 864 void MediaStreamImpl::UserMediaRequestInfo::OnTrackStarted( | 
|  | 865     MediaStreamSource* source, bool success) { | 
|  | 866   DVLOG(1) << "OnTrackStarted"; | 
|  | 867   std::vector<MediaStreamSource*>::iterator it = | 
|  | 868       std::find(sources_waiting_for_callback_.begin(), | 
|  | 869                 sources_waiting_for_callback_.end(), | 
|  | 870                 source); | 
|  | 871   DCHECK(it != sources_waiting_for_callback_.end()); | 
|  | 872   sources_waiting_for_callback_.erase(it); | 
|  | 873   // All tracks must be started successfully. Otherwise the request is a | 
|  | 874   // failure. | 
|  | 875   if (!success) | 
|  | 876     request_failed_ = true; | 
|  | 877   CheckAllTracksStarted(); | 
|  | 878 } | 
|  | 879 | 
|  | 880 void MediaStreamImpl::UserMediaRequestInfo::CheckAllTracksStarted() { | 
|  | 881   if (!ready_callback_.is_null() && sources_waiting_for_callback_.empty()) | 
|  | 882     ready_callback_.Run(this, !request_failed_); | 
|  | 883 } | 
|  | 884 | 
|  | 885 bool MediaStreamImpl::UserMediaRequestInfo::IsSourceUsed( | 
|  | 886     const blink::WebMediaStreamSource& source) const { | 
|  | 887   for (std::vector<blink::WebMediaStreamSource>::const_iterator source_it = | 
|  | 888            sources_.begin(); | 
|  | 889        source_it != sources_.end(); ++source_it) { | 
|  | 890     if (source_it->id() == source.id()) | 
|  | 891       return true; | 
|  | 892   } | 
|  | 893   return false; | 
|  | 894 } | 
|  | 895 | 
|  | 896 void MediaStreamImpl::UserMediaRequestInfo::RemoveSource( | 
|  | 897     const blink::WebMediaStreamSource& source) { | 
|  | 898   for (std::vector<blink::WebMediaStreamSource>::iterator it = | 
|  | 899            sources_.begin(); | 
|  | 900        it != sources_.end(); ++it) { | 
|  | 901     if (source.id() == it->id()) { | 
|  | 902       sources_.erase(it); | 
|  | 903       return; | 
|  | 904     } | 
|  | 905   } | 
| 867 } | 906 } | 
| 868 | 907 | 
| 869 }  // namespace content | 908 }  // namespace content | 
| OLD | NEW | 
|---|