 Chromium Code Reviews
 Chromium Code Reviews Issue 131763002:
  Adds MediaStreamSource, MediaStreamAudioSource and MediaStreamVideoCaptureDeviceSource  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 131763002:
  Adds MediaStreamSource, MediaStreamAudioSource and MediaStreamVideoCaptureDeviceSource  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 device_it != video_array.end(); ++device_it) { | 303 device_it != video_array.end(); ++device_it) { | 
| 315 if (!FindLocalSource(*device_it)) | 304 if (!FindLocalSource(*device_it)) | 
| 316 media_stream_dispatcher_->StopStreamDevice(*device_it); | 305 media_stream_dispatcher_->StopStreamDevice(*device_it); | 
| 317 } | 306 } | 
| 318 | 307 | 
| 319 DVLOG(1) << "Request ID not found"; | 308 DVLOG(1) << "Request ID not found"; | 
| 320 return; | 309 return; | 
| 321 } | 310 } | 
| 322 request_info->generated = true; | 311 request_info->generated = true; | 
| 323 | 312 | 
| 324 blink::WebVector<blink::WebMediaStreamSource> audio_source_vector( | |
| 325 audio_array.size()); | |
| 326 | |
| 327 // Log the device names for this request. | |
| 328 for (StreamDeviceInfoArray::const_iterator it = audio_array.begin(); | |
| 329 it != audio_array.end(); ++it) { | |
| 330 WebRtcLogMessage(base::StringPrintf( | |
| 331 "Generated media stream for request id %d contains audio device name" | |
| 332 " \"%s\"", | |
| 333 request_id, | |
| 334 it->device.name.c_str())); | |
| 335 } | |
| 336 | |
| 337 StreamDeviceInfoArray overridden_audio_array = audio_array; | |
| 338 if (!request_info->enable_automatic_output_device_selection) { | |
| 339 // If the GetUserMedia request did not explicitly set the constraint | |
| 340 // kMediaStreamRenderToAssociatedSink, the output device parameters must | |
| 341 // be removed. | |
| 342 for (StreamDeviceInfoArray::iterator it = overridden_audio_array.begin(); | |
| 343 it != overridden_audio_array.end(); ++it) { | |
| 344 it->device.matched_output_device_id = ""; | |
| 345 it->device.matched_output = MediaStreamDevice::AudioDeviceParameters(); | |
| 346 } | |
| 347 } | |
| 348 CreateWebKitSourceVector(label, overridden_audio_array, | |
| 349 blink::WebMediaStreamSource::TypeAudio, | |
| 350 request_info->frame, | |
| 351 audio_source_vector); | |
| 352 | |
| 353 blink::WebVector<blink::WebMediaStreamSource> video_source_vector( | |
| 354 video_array.size()); | |
| 355 CreateWebKitSourceVector(label, video_array, | |
| 356 blink::WebMediaStreamSource::TypeVideo, | |
| 357 request_info->frame, | |
| 358 video_source_vector); | |
| 359 blink::WebUserMediaRequest* request = &(request_info->request); | |
| 360 blink::WebString webkit_id = base::UTF8ToUTF16(label); | |
| 361 blink::WebMediaStream* web_stream = &(request_info->web_stream); | |
| 362 | |
| 363 blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector( | |
| 364 audio_array.size()); | |
| 365 for (size_t i = 0; i < audio_track_vector.size(); ++i) { | |
| 366 audio_track_vector[i].initialize(audio_source_vector[i]); | |
| 367 request_info->sources.push_back(audio_source_vector[i]); | |
| 368 } | |
| 369 | |
| 370 blink::WebVector<blink::WebMediaStreamTrack> video_track_vector( | |
| 371 video_array.size()); | |
| 372 for (size_t i = 0; i < video_track_vector.size(); ++i) { | |
| 373 video_track_vector[i].initialize(video_source_vector[i]); | |
| 374 request_info->sources.push_back(video_source_vector[i]); | |
| 375 } | |
| 376 | |
| 377 web_stream->initialize(webkit_id, audio_track_vector, | |
| 378 video_track_vector); | |
| 379 | |
| 380 // WebUserMediaRequest don't have an implementation in unit tests. | 313 // WebUserMediaRequest don't have an implementation in unit tests. | 
| 381 // Therefore we need to check for isNull here. | 314 // Therefore we need to check for isNull here. | 
| 315 blink::WebUserMediaRequest* request = &(request_info->request); | |
| 382 blink::WebMediaConstraints audio_constraints = request->isNull() ? | 316 blink::WebMediaConstraints audio_constraints = request->isNull() ? | 
| 383 blink::WebMediaConstraints() : request->audioConstraints(); | 317 blink::WebMediaConstraints() : request->audioConstraints(); | 
| 384 blink::WebMediaConstraints video_constraints = request->isNull() ? | 318 blink::WebMediaConstraints video_constraints = request->isNull() ? | 
| 385 blink::WebMediaConstraints() : request->videoConstraints(); | 319 blink::WebMediaConstraints() : request->videoConstraints(); | 
| 386 | 320 | 
| 387 dependency_factory_->CreateNativeMediaSources( | 321 blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector( | 
| 388 RenderViewObserver::routing_id(), | 322 audio_array.size()); | 
| 389 audio_constraints, video_constraints, web_stream, | 323 CreateAudioTracks(audio_array, audio_constraints, &audio_track_vector, | 
| 390 base::Bind(&MediaStreamImpl::OnCreateNativeSourcesComplete, AsWeakPtr())); | 324 request_info); | 
| 325 | |
| 326 blink::WebVector<blink::WebMediaStreamTrack> video_track_vector( | |
| 327 video_array.size()); | |
| 328 CreateVideoTracks(video_array, video_constraints, &video_track_vector, | |
| 329 request_info); | |
| 330 | |
| 331 blink::WebString webkit_id = base::UTF8ToUTF16(label); | |
| 332 blink::WebMediaStream* web_stream = &(request_info->web_stream); | |
| 333 | |
| 334 web_stream->initialize(webkit_id, audio_track_vector, | |
| 335 video_track_vector); | |
| 336 | |
| 337 // Wait for the tracks to be started successfully or to fail. | |
| 338 request_info->CallbackOnTracksStarted( | |
| 339 base::Bind(&MediaStreamImpl::OnCreateNativeTracksComplete, AsWeakPtr())); | |
| 391 } | 340 } | 
| 392 | 341 | 
| 393 // Callback from MediaStreamDispatcher. | 342 // Callback from MediaStreamDispatcher. | 
| 394 // The requested stream failed to be generated. | 343 // The requested stream failed to be generated. | 
| 395 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { | 344 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { | 
| 396 DCHECK(CalledOnValidThread()); | 345 DCHECK(CalledOnValidThread()); | 
| 397 DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" | 346 DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" | 
| 398 << request_id << ")"; | 347 << request_id << ")"; | 
| 399 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id); | 348 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id); | 
| 400 if (!request_info) { | 349 if (!request_info) { | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 local_sources_.erase(device_it); | 385 local_sources_.erase(device_it); | 
| 437 break; | 386 break; | 
| 438 } | 387 } | 
| 439 } | 388 } | 
| 440 | 389 | 
| 441 // Remove the reference to this source from all |user_media_requests_|. | 390 // Remove the reference to this source from all |user_media_requests_|. | 
| 442 // TODO(perkj): The below is not necessary once we don't need to support | 391 // TODO(perkj): The below is not necessary once we don't need to support | 
| 443 // MediaStream::Stop(). | 392 // MediaStream::Stop(). | 
| 444 UserMediaRequests::iterator it = user_media_requests_.begin(); | 393 UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 445 while (it != user_media_requests_.end()) { | 394 while (it != user_media_requests_.end()) { | 
| 446 RemoveSource(source, &(*it)->sources); | 395 (*it)->RemoveSource(source); | 
| 447 if ((*it)->sources.empty()) { | 396 if ((*it)->IsAllSourcesRemoved()) { | 
| 448 it = user_media_requests_.erase(it); | 397 it = user_media_requests_.erase(it); | 
| 449 } else { | 398 } else { | 
| 450 ++it; | 399 ++it; | 
| 451 } | 400 } | 
| 452 } | 401 } | 
| 453 } | 402 } | 
| 454 | 403 | 
| 455 void MediaStreamImpl::CreateWebKitSourceVector( | 404 void MediaStreamImpl::InitializeSourceObject( | 
| 456 const std::string& label, | 405 const StreamDeviceInfo& device, | 
| 406 blink::WebMediaStreamSource::Type type, | |
| 407 const blink::WebMediaConstraints& constraints, | |
| 408 blink::WebFrame* frame, | |
| 409 blink::WebMediaStreamSource* webkit_source) { | |
| 410 const blink::WebMediaStreamSource* existing_source = | |
| 411 FindLocalSource(device); | |
| 412 if (existing_source) { | |
| 413 *webkit_source = *existing_source; | |
| 414 DVLOG(1) << "Source already exist. Reusing source with id " | |
| 415 << webkit_source->id().utf8(); | |
| 
no longer working on chromium
2014/01/20 13:36:20
nit, indentation.
 
perkj_chrome
2014/01/20 16:12:06
Done.
 | |
| 416 return; | |
| 417 } | |
| 418 | |
| 419 webkit_source->initialize( | |
| 420 base::UTF8ToUTF16(device.device.id), | |
| 421 type, | |
| 422 base::UTF8ToUTF16(device.device.name)); | |
| 423 | |
| 424 DVLOG(1) << "Initialize source object :" | |
| 425 << "id = " << webkit_source->id().utf8() | |
| 426 << ", name = " << webkit_source->name().utf8(); | |
| 427 | |
| 428 if (type == blink::WebMediaStreamSource::TypeVideo) { | |
| 429 MediaStreamVideoCapturerSource* video_source( | |
| 430 new content::MediaStreamVideoCapturerSource( | |
| 431 device, | |
| 432 base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr()), | |
| 433 dependency_factory_)); | |
| 434 webkit_source->setExtraData(video_source); | |
| 435 } else { | |
| 436 DCHECK_EQ(blink::WebMediaStreamSource::TypeAudio, type); | |
| 437 MediaStreamAudioSource* audio_source( | |
| 438 new MediaStreamAudioSource( | |
| 439 device, | |
| 440 base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr()))); | |
| 441 webkit_source->setExtraData(audio_source); | |
| 442 // TODO(xians): Move initialization from MediaStreamDependencyFactory | |
| 443 // to MediaStreamAudioSource. | |
| 444 dependency_factory_->InitializeMediaStreamAudioSource( | |
| 445 RenderViewObserver::routing_id(), | |
| 446 constraints, | |
| 447 *webkit_source); | |
| 448 } | |
| 449 local_sources_.push_back(LocalStreamSource(frame, *webkit_source)); | |
| 450 return; | |
| 
no longer working on chromium
2014/01/20 13:36:20
nit, remove the return
 
perkj_chrome
2014/01/20 16:12:06
Done.
 | |
| 451 } | |
| 452 | |
| 453 void MediaStreamImpl::CreateVideoTracks( | |
| 457 const StreamDeviceInfoArray& devices, | 454 const StreamDeviceInfoArray& devices, | 
| 458 blink::WebMediaStreamSource::Type type, | 455 const blink::WebMediaConstraints& constraints, | 
| 459 blink::WebFrame* frame, | 456 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, | 
| 460 blink::WebVector<blink::WebMediaStreamSource>& webkit_sources) { | 457 UserMediaRequestInfo* request) { | 
| 461 CHECK_EQ(devices.size(), webkit_sources.size()); | 458 DCHECK_EQ(devices.size(), webkit_tracks->size()); | 
| 459 | |
| 462 for (size_t i = 0; i < devices.size(); ++i) { | 460 for (size_t i = 0; i < devices.size(); ++i) { | 
| 463 const blink::WebMediaStreamSource* existing_source = | 461 blink::WebMediaStreamSource webkit_source; | 
| 464 FindLocalSource(devices[i]); | 462 InitializeSourceObject(devices[i], | 
| 465 if (existing_source) { | 463 blink::WebMediaStreamSource::TypeVideo, | 
| 466 webkit_sources[i] = *existing_source; | 464 constraints, | 
| 467 DVLOG(1) << "Source already exist. Reusing source with id " | 465 request->frame, | 
| 468 << webkit_sources[i]. id().utf8(); | 466 &webkit_source); | 
| 469 continue; | 467 (*webkit_tracks)[i].initialize(webkit_source); | 
| 470 } | 468 request->StartTrack((*webkit_tracks)[i], constraints); | 
| 471 webkit_sources[i].initialize( | |
| 472 base::UTF8ToUTF16(devices[i].device.id), | |
| 473 type, | |
| 474 base::UTF8ToUTF16(devices[i].device.name)); | |
| 475 MediaStreamSourceExtraData* source_extra_data( | |
| 476 new content::MediaStreamSourceExtraData( | |
| 477 devices[i], | |
| 478 base::Bind(&MediaStreamImpl::OnLocalSourceStop, AsWeakPtr()))); | |
| 479 // |source_extra_data| is owned by webkit_sources[i]. | |
| 480 webkit_sources[i].setExtraData(source_extra_data); | |
| 481 local_sources_.push_back(LocalStreamSource(frame, webkit_sources[i])); | |
| 482 } | 469 } | 
| 483 } | 470 } | 
| 484 | 471 | 
| 485 // Callback from MediaStreamDependencyFactory when the sources in |web_stream| | 472 void MediaStreamImpl::CreateAudioTracks( | 
| 486 // have been generated. | 473 const StreamDeviceInfoArray& devices, | 
| 487 void MediaStreamImpl::OnCreateNativeSourcesComplete( | 474 const blink::WebMediaConstraints& constraints, | 
| 488 blink::WebMediaStream* web_stream, | 475 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, | 
| 489 bool request_succeeded) { | 476 UserMediaRequestInfo* request) { | 
| 490 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(web_stream); | 477 DCHECK_EQ(devices.size(), webkit_tracks->size()); | 
| 491 if (!request_info) { | 478 | 
| 492 // This can happen if the request is canceled or the frame reloads while | 479 // Log the device names for this request. | 
| 493 // MediaStreamDependencyFactory is creating the sources. | 480 for (StreamDeviceInfoArray::const_iterator it = devices.begin(); | 
| 494 DVLOG(1) << "Request ID not found"; | 481 it != devices.end(); ++it) { | 
| 495 return; | 482 WebRtcLogMessage(base::StringPrintf( | 
| 483 "Generated media stream for request id %d contains audio device name" | |
| 484 " \"%s\"", | |
| 485 request->request_id, | |
| 486 it->device.name.c_str())); | |
| 496 } | 487 } | 
| 497 | 488 | 
| 489 StreamDeviceInfoArray overridden_audio_array = devices; | |
| 490 if (!request->enable_automatic_output_device_selection) { | |
| 491 // If the GetUserMedia request did not explicitly set the constraint | |
| 492 // kMediaStreamRenderToAssociatedSink, the output device parameters must | |
| 493 // be removed. | |
| 494 for (StreamDeviceInfoArray::iterator it = overridden_audio_array.begin(); | |
| 495 it != overridden_audio_array.end(); ++it) { | |
| 496 it->device.matched_output_device_id = ""; | |
| 497 it->device.matched_output = MediaStreamDevice::AudioDeviceParameters(); | |
| 498 } | |
| 499 } | |
| 500 | |
| 501 for (size_t i = 0; i < overridden_audio_array.size(); ++i) { | |
| 502 blink::WebMediaStreamSource webkit_source; | |
| 503 InitializeSourceObject(overridden_audio_array[i], | |
| 504 blink::WebMediaStreamSource::TypeAudio, | |
| 505 constraints, | |
| 506 request->frame, | |
| 507 &webkit_source); | |
| 508 (*webkit_tracks)[i].initialize(webkit_source); | |
| 509 request->StartTrack((*webkit_tracks)[i], constraints); | |
| 510 } | |
| 511 } | |
| 512 | |
| 513 void MediaStreamImpl::OnCreateNativeTracksComplete( | |
| 
no longer working on chromium
2014/01/20 13:36:20
nit, s/OnCreateNativeTracksCompleted/OnCreateNativ
 
perkj_chrome
2014/01/20 16:12:06
Done.
 | |
| 514 UserMediaRequestInfo* request, | |
| 515 bool request_succeeded) { | |
| 498 // Create a native representation of the stream. | 516 // Create a native representation of the stream. | 
| 499 if (request_succeeded) { | 517 if (request_succeeded) { | 
| 500 dependency_factory_->CreateNativeLocalMediaStream( | 518 dependency_factory_->CreateNativeLocalMediaStream( | 
| 501 web_stream, | 519 &request->web_stream, | 
| 502 base::Bind(&MediaStreamImpl::OnLocalMediaStreamStop, AsWeakPtr())); | 520 base::Bind(&MediaStreamImpl::OnLocalMediaStreamStop, AsWeakPtr())); | 
| 503 } | 521 } | 
| 504 DVLOG(1) << "MediaStreamImpl::OnCreateNativeSourcesComplete(" | 522 DVLOG(1) << "MediaStreamImpl::OnCreateNativeTracksComplete(" | 
| 505 << "{request_id = " << request_info->request_id << "} " | 523 << "{request_id = " << request->request_id << "} " | 
| 506 << "{request_succeeded = " << request_succeeded << "})"; | 524 << "{request_succeeded = " << request_succeeded << "})"; | 
| 507 CompleteGetUserMediaRequest(request_info->web_stream, &request_info->request, | 525 CompleteGetUserMediaRequest(request->web_stream, &request->request, | 
| 508 request_succeeded); | 526 request_succeeded); | 
| 509 if (!request_succeeded) { | 527 if (!request_succeeded) { | 
| 510 // TODO(perkj): Once we don't support MediaStream::Stop the |request_info| | 528 // TODO(perkj): Once we don't support MediaStream::Stop the |request_info| | 
| 511 // can be deleted even if the request succeeds. | 529 // can be deleted even if the request succeeds. | 
| 512 DeleteUserMediaRequestInfo(request_info); | 530 DeleteUserMediaRequestInfo(request); | 
| 513 StopUnreferencedSources(true); | 531 StopUnreferencedSources(true); | 
| 514 } | 532 } | 
| 515 } | 533 } | 
| 516 | 534 | 
| 517 void MediaStreamImpl::OnDevicesEnumerated( | 535 void MediaStreamImpl::OnDevicesEnumerated( | 
| 518 int request_id, | 536 int request_id, | 
| 519 const StreamDeviceInfoArray& device_array) { | 537 const StreamDeviceInfoArray& device_array) { | 
| 520 DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" | 538 DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" | 
| 521 << request_id << ")"; | 539 << request_id << ")"; | 
| 522 NOTIMPLEMENTED(); | 540 NOTIMPLEMENTED(); | 
| (...skipping 22 matching lines...) Expand all Loading... | |
| 545 request_info->requestSucceeded(stream); | 563 request_info->requestSucceeded(stream); | 
| 546 } else { | 564 } else { | 
| 547 request_info->requestFailed(); | 565 request_info->requestFailed(); | 
| 548 } | 566 } | 
| 549 } | 567 } | 
| 550 | 568 | 
| 551 const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource( | 569 const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource( | 
| 552 const StreamDeviceInfo& device) const { | 570 const StreamDeviceInfo& device) const { | 
| 553 for (LocalStreamSources::const_iterator it = local_sources_.begin(); | 571 for (LocalStreamSources::const_iterator it = local_sources_.begin(); | 
| 554 it != local_sources_.end(); ++it) { | 572 it != local_sources_.end(); ++it) { | 
| 555 MediaStreamSourceExtraData* extra_data = | 573 MediaStreamSource* source = | 
| 556 static_cast<MediaStreamSourceExtraData*>( | 574 static_cast<MediaStreamSource*>(it->source.extraData()); | 
| 557 it->source.extraData()); | 575 const StreamDeviceInfo& active_device = source->device_info(); | 
| 558 const StreamDeviceInfo& active_device = extra_data->device_info(); | |
| 559 if (active_device.device.id == device.device.id && | 576 if (active_device.device.id == device.device.id && | 
| 560 active_device.device.type == device.device.type && | 577 active_device.device.type == device.device.type && | 
| 561 active_device.session_id == device.session_id) { | 578 active_device.session_id == device.session_id) { | 
| 562 return &it->source; | 579 return &it->source; | 
| 563 } | 580 } | 
| 564 } | 581 } | 
| 565 return NULL; | 582 return NULL; | 
| 566 } | 583 } | 
| 567 | 584 | 
| 568 bool MediaStreamImpl::FindSourceInRequests( | 585 bool MediaStreamImpl::FindSourceInRequests( | 
| 
no longer working on chromium
2014/01/20 13:36:20
nit, this method returns true or false depending o
 
perkj_chrome
2014/01/20 16:12:06
Done.
 | |
| 569 const blink::WebMediaStreamSource& source) const { | 586 const blink::WebMediaStreamSource& source) const { | 
| 570 for (UserMediaRequests::const_iterator req_it = user_media_requests_.begin(); | 587 for (UserMediaRequests::const_iterator req_it = user_media_requests_.begin(); | 
| 571 req_it != user_media_requests_.end(); ++req_it) { | 588 req_it != user_media_requests_.end(); ++req_it) { | 
| 572 const std::vector<blink::WebMediaStreamSource>& sources = | 589 if ((*req_it)->IsSourceUsed(source)) | 
| 573 (*req_it)->sources; | 590 return true; | 
| 574 for (std::vector<blink::WebMediaStreamSource>::const_iterator source_it = | |
| 575 sources.begin(); | |
| 576 source_it != sources.end(); ++source_it) { | |
| 577 if (source_it->id() == source.id()) { | |
| 578 return true; | |
| 579 } | |
| 580 } | |
| 581 } | 591 } | 
| 582 return false; | 592 return false; | 
| 583 } | 593 } | 
| 584 | 594 | 
| 585 MediaStreamImpl::UserMediaRequestInfo* | 595 MediaStreamImpl::UserMediaRequestInfo* | 
| 586 MediaStreamImpl::FindUserMediaRequestInfo(int request_id) { | 596 MediaStreamImpl::FindUserMediaRequestInfo(int request_id) { | 
| 587 UserMediaRequests::iterator it = user_media_requests_.begin(); | 597 UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 588 for (; it != user_media_requests_.end(); ++it) { | 598 for (; it != user_media_requests_.end(); ++it) { | 
| 589 if ((*it)->request_id == request_id) | 599 if ((*it)->request_id == request_id) | 
| 590 return (*it); | 600 return (*it); | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 606 MediaStreamImpl::UserMediaRequestInfo* | 616 MediaStreamImpl::UserMediaRequestInfo* | 
| 607 MediaStreamImpl::FindUserMediaRequestInfo(const std::string& label) { | 617 MediaStreamImpl::FindUserMediaRequestInfo(const std::string& label) { | 
| 608 UserMediaRequests::iterator it = user_media_requests_.begin(); | 618 UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 609 for (; it != user_media_requests_.end(); ++it) { | 619 for (; it != user_media_requests_.end(); ++it) { | 
| 610 if ((*it)->generated && (*it)->web_stream.id() == base::UTF8ToUTF16(label)) | 620 if ((*it)->generated && (*it)->web_stream.id() == base::UTF8ToUTF16(label)) | 
| 611 return (*it); | 621 return (*it); | 
| 612 } | 622 } | 
| 613 return NULL; | 623 return NULL; | 
| 614 } | 624 } | 
| 615 | 625 | 
| 616 MediaStreamImpl::UserMediaRequestInfo* | |
| 617 MediaStreamImpl::FindUserMediaRequestInfo( | |
| 618 blink::WebMediaStream* web_stream) { | |
| 619 UserMediaRequests::iterator it = user_media_requests_.begin(); | |
| 620 for (; it != user_media_requests_.end(); ++it) { | |
| 621 if (&((*it)->web_stream) == web_stream) | |
| 622 return (*it); | |
| 623 } | |
| 624 return NULL; | |
| 625 } | |
| 626 | |
| 627 void MediaStreamImpl::DeleteUserMediaRequestInfo( | 626 void MediaStreamImpl::DeleteUserMediaRequestInfo( | 
| 628 UserMediaRequestInfo* request) { | 627 UserMediaRequestInfo* request) { | 
| 629 UserMediaRequests::iterator it = user_media_requests_.begin(); | 628 UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 630 for (; it != user_media_requests_.end(); ++it) { | 629 for (; it != user_media_requests_.end(); ++it) { | 
| 631 if ((*it) == request) { | 630 if ((*it) == request) { | 
| 632 user_media_requests_.erase(it); | 631 user_media_requests_.erase(it); | 
| 633 return; | 632 return; | 
| 634 } | 633 } | 
| 635 } | 634 } | 
| 636 NOTREACHED(); | 635 NOTREACHED(); | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 const std::string& label) { | 679 const std::string& label) { | 
| 681 DVLOG(1) << "MediaStreamImpl::OnLocalMediaStreamStop(" << label << ")"; | 680 DVLOG(1) << "MediaStreamImpl::OnLocalMediaStreamStop(" << label << ")"; | 
| 682 | 681 | 
| 683 UserMediaRequestInfo* user_media_request = FindUserMediaRequestInfo(label); | 682 UserMediaRequestInfo* user_media_request = FindUserMediaRequestInfo(label); | 
| 684 if (user_media_request) { | 683 if (user_media_request) { | 
| 685 DeleteUserMediaRequestInfo(user_media_request); | 684 DeleteUserMediaRequestInfo(user_media_request); | 
| 686 } | 685 } | 
| 687 StopUnreferencedSources(true); | 686 StopUnreferencedSources(true); | 
| 688 } | 687 } | 
| 689 | 688 | 
| 690 void MediaStreamImpl::OnLocalSourceStop( | 689 void MediaStreamImpl::OnLocalSourceStopped( | 
| 691 const blink::WebMediaStreamSource& source) { | 690 const blink::WebMediaStreamSource& source) { | 
| 692 DCHECK(CalledOnValidThread()); | 691 DCHECK(CalledOnValidThread()); | 
| 693 | 692 | 
| 694 StopLocalSource(source, true); | |
| 695 | |
| 696 bool device_found = false; | 693 bool device_found = false; | 
| 697 for (LocalStreamSources::iterator device_it = local_sources_.begin(); | 694 for (LocalStreamSources::iterator device_it = local_sources_.begin(); | 
| 698 device_it != local_sources_.end(); ++device_it) { | 695 device_it != local_sources_.end(); ++device_it) { | 
| 699 if (device_it->source.id() == source.id()) { | 696 if (device_it->source.id() == source.id()) { | 
| 700 device_found = true; | 697 device_found = true; | 
| 701 local_sources_.erase(device_it); | 698 local_sources_.erase(device_it); | 
| 702 break; | 699 break; | 
| 703 } | 700 } | 
| 704 } | 701 } | 
| 705 CHECK(device_found); | 702 CHECK(device_found); | 
| 706 | 703 | 
| 707 // Remove the reference to this source from all |user_media_requests_|. | 704 // Remove the reference to this source from all |user_media_requests_|. | 
| 708 // TODO(perkj): The below is not necessary once we don't need to support | 705 // TODO(perkj): The below is not necessary once we don't need to support | 
| 709 // MediaStream::Stop(). | 706 // MediaStream::Stop(). | 
| 710 UserMediaRequests::iterator it = user_media_requests_.begin(); | 707 UserMediaRequests::iterator it = user_media_requests_.begin(); | 
| 711 while (it != user_media_requests_.end()) { | 708 while (it != user_media_requests_.end()) { | 
| 712 RemoveSource(source, &(*it)->sources); | 709 (*it)->RemoveSource(source); | 
| 713 if ((*it)->sources.empty()) { | 710 if ((*it)->IsAllSourcesRemoved()) { | 
| 714 it = user_media_requests_.erase(it); | 711 it = user_media_requests_.erase(it); | 
| 715 } else { | 712 } else { | 
| 716 ++it; | 713 ++it; | 
| 717 } | 714 } | 
| 718 } | 715 } | 
| 716 | |
| 717 MediaStreamSource* source_impl = | |
| 718 static_cast<MediaStreamSource*> (source.extraData()); | |
| 719 media_stream_dispatcher_->StopStreamDevice(source_impl->device_info()); | |
| 719 } | 720 } | 
| 720 | 721 | 
| 721 void MediaStreamImpl::StopLocalSource( | 722 void MediaStreamImpl::StopLocalSource( | 
| 722 const blink::WebMediaStreamSource& source, | 723 const blink::WebMediaStreamSource& source, | 
| 723 bool notify_dispatcher) { | 724 bool notify_dispatcher) { | 
| 724 MediaStreamSourceExtraData* extra_data = | 725 MediaStreamSource* source_impl = | 
| 725 static_cast<MediaStreamSourceExtraData*> (source.extraData()); | 726 static_cast<MediaStreamSource*> (source.extraData()); | 
| 726 CHECK(extra_data); | |
| 727 DVLOG(1) << "MediaStreamImpl::StopLocalSource(" | 727 DVLOG(1) << "MediaStreamImpl::StopLocalSource(" | 
| 728 << "{device_id = " << extra_data->device_info().device.id << "})"; | 728 << "{device_id = " << source_impl->device_info().device.id << "})"; | 
| 729 | |
| 730 if (source.type() == blink::WebMediaStreamSource::TypeAudio) { | |
| 731 if (extra_data->GetAudioCapturer()) | |
| 732 extra_data->GetAudioCapturer()->Stop(); | |
| 733 } | |
| 734 | 729 | 
| 735 if (notify_dispatcher) | 730 if (notify_dispatcher) | 
| 736 media_stream_dispatcher_->StopStreamDevice(extra_data->device_info()); | 731 media_stream_dispatcher_->StopStreamDevice(source_impl->device_info()); | 
| 737 | 732 | 
| 738 blink::WebMediaStreamSource writable_source(source); | 733 source_impl->ResetSourceStoppedCallback(); | 
| 739 writable_source.setReadyState( | 734 source_impl->StopSource(); | 
| 740 blink::WebMediaStreamSource::ReadyStateEnded); | |
| 741 writable_source.setExtraData(NULL); | |
| 742 } | 735 } | 
| 743 | 736 | 
| 744 void MediaStreamImpl::StopUnreferencedSources(bool notify_dispatcher) { | 737 void MediaStreamImpl::StopUnreferencedSources(bool notify_dispatcher) { | 
| 745 LocalStreamSources::iterator source_it = local_sources_.begin(); | 738 LocalStreamSources::iterator source_it = local_sources_.begin(); | 
| 746 while (source_it != local_sources_.end()) { | 739 while (source_it != local_sources_.end()) { | 
| 747 if (!FindSourceInRequests(source_it->source)) { | 740 if (!FindSourceInRequests(source_it->source)) { | 
| 748 StopLocalSource(source_it->source, notify_dispatcher); | 741 StopLocalSource(source_it->source, notify_dispatcher); | 
| 749 source_it = local_sources_.erase(source_it); | 742 source_it = local_sources_.erase(source_it); | 
| 750 } else { | 743 } else { | 
| 751 ++source_it; | 744 ++source_it; | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 802 DCHECK(CalledOnValidThread()); | 795 DCHECK(CalledOnValidThread()); | 
| 803 WebRtcAudioDeviceImpl* audio_device = | 796 WebRtcAudioDeviceImpl* audio_device = | 
| 804 dependency_factory_->GetWebRtcAudioDevice(); | 797 dependency_factory_->GetWebRtcAudioDevice(); | 
| 805 if (!audio_device) | 798 if (!audio_device) | 
| 806 return false; | 799 return false; | 
| 807 | 800 | 
| 808 return audio_device->GetAuthorizedDeviceInfoForAudioRenderer( | 801 return audio_device->GetAuthorizedDeviceInfoForAudioRenderer( | 
| 809 session_id, output_sample_rate, output_frames_per_buffer); | 802 session_id, output_sample_rate, output_frames_per_buffer); | 
| 810 } | 803 } | 
| 811 | 804 | 
| 812 MediaStreamSourceExtraData::MediaStreamSourceExtraData( | |
| 813 const StreamDeviceInfo& device_info, | |
| 814 const SourceStopCallback& stop_callback) | |
| 815 : device_info_(device_info), | |
| 816 stop_callback_(stop_callback) { | |
| 817 } | |
| 818 | |
| 819 MediaStreamSourceExtraData::MediaStreamSourceExtraData() { | |
| 820 } | |
| 821 | |
| 822 MediaStreamSourceExtraData::~MediaStreamSourceExtraData() {} | |
| 823 | |
| 824 void MediaStreamSourceExtraData::OnLocalSourceStop() { | |
| 825 if (!stop_callback_.is_null()) | |
| 826 stop_callback_.Run(owner()); | |
| 827 } | |
| 828 | |
| 829 MediaStreamExtraData::MediaStreamExtraData( | 805 MediaStreamExtraData::MediaStreamExtraData( | 
| 830 webrtc::MediaStreamInterface* stream, bool is_local) | 806 webrtc::MediaStreamInterface* stream, bool is_local) | 
| 831 : stream_(stream), | 807 : stream_(stream), | 
| 832 is_local_(is_local) { | 808 is_local_(is_local) { | 
| 833 } | 809 } | 
| 834 | 810 | 
| 835 MediaStreamExtraData::~MediaStreamExtraData() { | 811 MediaStreamExtraData::~MediaStreamExtraData() { | 
| 836 } | 812 } | 
| 837 | 813 | 
| 838 void MediaStreamExtraData::SetLocalStreamStopCallback( | 814 void MediaStreamExtraData::SetLocalStreamStopCallback( | 
| 839 const StreamStopCallback& stop_callback) { | 815 const StreamStopCallback& stop_callback) { | 
| 840 stream_stop_callback_ = stop_callback; | 816 stream_stop_callback_ = stop_callback; | 
| 841 } | 817 } | 
| 842 | 818 | 
| 843 void MediaStreamExtraData::OnLocalStreamStop() { | 819 void MediaStreamExtraData::OnLocalStreamStop() { | 
| 844 if (!stream_stop_callback_.is_null()) | 820 if (!stream_stop_callback_.is_null()) | 
| 845 stream_stop_callback_.Run(stream_->label()); | 821 stream_stop_callback_.Run(stream_->label()); | 
| 846 } | 822 } | 
| 847 | 823 | 
| 848 MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo( | 824 MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo( | 
| 849 int request_id, | 825 int request_id, | 
| 850 blink::WebFrame* frame, | 826 blink::WebFrame* frame, | 
| 851 const blink::WebUserMediaRequest& request, | 827 const blink::WebUserMediaRequest& request, | 
| 852 bool enable_automatic_output_device_selection) | 828 bool enable_automatic_output_device_selection) | 
| 853 : request_id(request_id), | 829 : request_id(request_id), | 
| 854 generated(false), | 830 generated(false), | 
| 855 enable_automatic_output_device_selection( | 831 enable_automatic_output_device_selection( | 
| 856 enable_automatic_output_device_selection), | 832 enable_automatic_output_device_selection), | 
| 857 frame(frame), | 833 frame(frame), | 
| 858 request(request) { | 834 request(request), | 
| 835 request_failed_(false) { | |
| 859 } | 836 } | 
| 860 | 837 | 
| 861 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()) | |
| 
no longer working on chromium
2014/01/20 13:36:20
nit, is it possible to have ready_callback_ to be
 
perkj_chrome
2014/01/20 16:12:06
Yes- if the source is started before CheckAllTrack
 | |
| 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 } | |
| 862 } | 906 } | 
| 863 | 907 | 
| 864 } // namespace content | 908 } // namespace content | 
| OLD | NEW |