| 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 |