| 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/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 GetMandatoryStreamConstraint(user_media_request.videoConstraints(), | 61 GetMandatoryStreamConstraint(user_media_request.videoConstraints(), |
| 62 kMediaStreamSource) == | 62 kMediaStreamSource) == |
| 63 kMediaStreamSourceTab) { | 63 kMediaStreamSourceTab) { |
| 64 options->video_type = content::MEDIA_TAB_VIDEO_CAPTURE; | 64 options->video_type = content::MEDIA_TAB_VIDEO_CAPTURE; |
| 65 options->video_device_id = GetMandatoryStreamConstraint( | 65 options->video_device_id = GetMandatoryStreamConstraint( |
| 66 user_media_request.videoConstraints(), | 66 user_media_request.videoConstraints(), |
| 67 kMediaStreamSourceId); | 67 kMediaStreamSourceId); |
| 68 } | 68 } |
| 69 } | 69 } |
| 70 | 70 |
| 71 // Get session ID for the selected microphone to ensure that we start | |
| 72 // capturing audio using the correct input device. | |
| 73 static int GetSessionId(const WebKit::WebMediaStreamSource& source) { | |
| 74 MediaStreamSourceExtraData* source_data = | |
| 75 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | |
| 76 if (!source_data) { | |
| 77 // TODO(henrika): Implement support for sources from remote MediaStreams. | |
| 78 NOTIMPLEMENTED(); | |
| 79 return -1; | |
| 80 } | |
| 81 DVLOG(1) << "local audio track source name: " | |
| 82 << source_data->device_info().device.name; | |
| 83 | |
| 84 return source_data->device_info().session_id; | |
| 85 } | |
| 86 | |
| 87 static int g_next_request_id = 0; | 71 static int g_next_request_id = 0; |
| 88 | 72 |
| 89 // Creates a WebKit representation of a stream sources based on | 73 // Creates a WebKit representation of a stream sources based on |
| 90 // |devices| from the MediaStreamDispatcher. | 74 // |devices| from the MediaStreamDispatcher. |
| 91 void CreateWebKitSourceVector( | 75 void CreateWebKitSourceVector( |
| 92 const std::string& label, | 76 const std::string& label, |
| 93 const StreamDeviceInfoArray& devices, | 77 const StreamDeviceInfoArray& devices, |
| 94 WebKit::WebMediaStreamSource::Type type, | 78 WebKit::WebMediaStreamSource::Type type, |
| 95 WebKit::WebVector<WebKit::WebMediaStreamSource>& webkit_sources) { | 79 WebKit::WebVector<WebKit::WebMediaStreamSource>& webkit_sources) { |
| 96 CHECK_EQ(devices.size(), webkit_sources.size()); | 80 CHECK_EQ(devices.size(), webkit_sources.size()); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 CreateRemoteAudioRenderer(extra_data->remote_stream()); | 282 CreateRemoteAudioRenderer(extra_data->remote_stream()); |
| 299 | 283 |
| 300 if (renderer && | 284 if (renderer && |
| 301 dependency_factory_->GetWebRtcAudioDevice()->SetRenderer(renderer)) { | 285 dependency_factory_->GetWebRtcAudioDevice()->SetRenderer(renderer)) { |
| 302 return renderer; | 286 return renderer; |
| 303 } | 287 } |
| 304 | 288 |
| 305 // WebRtcAudioDeviceImpl can only support one renderer. | 289 // WebRtcAudioDeviceImpl can only support one renderer. |
| 306 return NULL; | 290 return NULL; |
| 307 } else if (extra_data->local_stream()) { | 291 } else if (extra_data->local_stream()) { |
| 308 DVLOG(1) << "creating local audio renderer for stream:" | 292 // Create the local audio renderer if the stream contains audio tracks. |
| 309 << extra_data->local_stream()->label(); | 293 return CreateLocalAudioRenderer(extra_data->local_stream()); |
| 310 | |
| 311 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; | |
| 312 descriptor.audioSources(audio_components); | |
| 313 if (audio_components.size() != 1) { | |
| 314 // TODO(henrika): add support for more than one audio track. | |
| 315 LOG(WARNING) << "Multiple MediaStream audio tracks not supported"; | |
| 316 return NULL; | |
| 317 } | |
| 318 | |
| 319 if (!audio_components[0].isEnabled()) { | |
| 320 DVLOG(1) << "audio track is disabled"; | |
| 321 return NULL; | |
| 322 } | |
| 323 | |
| 324 int session_id = 0; | |
| 325 const WebKit::WebMediaStreamSource& source = audio_components[0].source(); | |
| 326 if (!source.requiresAudioConsumer()) { | |
| 327 session_id = GetSessionId(source); | |
| 328 if (session_id == -1) { | |
| 329 return NULL; | |
| 330 } | |
| 331 } else { | |
| 332 DVLOG(1) << "WebAudio MediaStream is detected"; | |
| 333 session_id = -1; | |
| 334 } | |
| 335 | |
| 336 // Create the local audio renderer using the specified session ID. | |
| 337 scoped_refptr<WebRtcLocalAudioRenderer> local_renderer = | |
| 338 CreateLocalAudioRenderer(session_id); | |
| 339 return local_renderer; | |
| 340 } | 294 } |
| 341 | 295 |
| 342 NOTREACHED(); | 296 NOTREACHED(); |
| 343 return NULL; | 297 return NULL; |
| 344 } | 298 } |
| 345 | 299 |
| 346 // Callback from MediaStreamDispatcher. | 300 // Callback from MediaStreamDispatcher. |
| 347 // The requested stream have been generated by the MediaStreamDispatcher. | 301 // The requested stream have been generated by the MediaStreamDispatcher. |
| 348 void MediaStreamImpl::OnStreamGenerated( | 302 void MediaStreamImpl::OnStreamGenerated( |
| 349 int request_id, | 303 int request_id, |
| 350 const std::string& label, | 304 const std::string& label, |
| 351 const StreamDeviceInfoArray& audio_array, | 305 const StreamDeviceInfoArray& audio_array, |
| 352 const StreamDeviceInfoArray& video_array) { | 306 const StreamDeviceInfoArray& video_array) { |
| 353 DCHECK(CalledOnValidThread()); | 307 DCHECK(CalledOnValidThread()); |
| 354 DVLOG(1) << "MediaStreamImpl::OnStreamGenerated(" | 308 DVLOG(1) << "MediaStreamImpl::OnStreamGenerated stream:" << label; |
| 355 << request_id << "," << label << ")"; | |
| 356 | 309 |
| 357 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id); | 310 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id); |
| 358 if (!request_info) { | 311 if (!request_info) { |
| 359 // This can happen if the request is canceled or the frame reloads while | 312 // This can happen if the request is canceled or the frame reloads while |
| 360 // MediaStreamDispatcher is processing the request. | 313 // MediaStreamDispatcher is processing the request. |
| 361 // We need to tell the dispatcher to stop the stream. | 314 // We need to tell the dispatcher to stop the stream. |
| 362 media_stream_dispatcher_->StopStream(label); | 315 media_stream_dispatcher_->StopStream(label); |
| 363 DVLOG(1) << "Request ID not found"; | 316 DVLOG(1) << "Request ID not found"; |
| 364 return; | 317 return; |
| 365 } | 318 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 &request_info->request, | 365 &request_info->request, |
| 413 false); | 366 false); |
| 414 DeleteUserMediaRequestInfo(request_info); | 367 DeleteUserMediaRequestInfo(request_info); |
| 415 } | 368 } |
| 416 | 369 |
| 417 // Callback from MediaStreamDependencyFactory when the sources in |description| | 370 // Callback from MediaStreamDependencyFactory when the sources in |description| |
| 418 // have been generated. | 371 // have been generated. |
| 419 void MediaStreamImpl::OnCreateNativeSourcesComplete( | 372 void MediaStreamImpl::OnCreateNativeSourcesComplete( |
| 420 WebKit::WebMediaStreamDescriptor* description, | 373 WebKit::WebMediaStreamDescriptor* description, |
| 421 bool request_succeeded) { | 374 bool request_succeeded) { |
| 375 DVLOG(1) << "MediaStreamImpl::OnCreateNativeSourcesComplete stream:" |
| 376 << UTF16ToUTF8(description->label()); |
| 422 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(description); | 377 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(description); |
| 423 if (!request_info) { | 378 if (!request_info) { |
| 424 // This can happen if the request is canceled or the frame reloads while | 379 // This can happen if the request is canceled or the frame reloads while |
| 425 // MediaStreamDependencyFactory is creating the sources. | 380 // MediaStreamDependencyFactory is creating the sources. |
| 426 DVLOG(1) << "Request ID not found"; | 381 DVLOG(1) << "Request ID not found"; |
| 427 return; | 382 return; |
| 428 } | 383 } |
| 429 | 384 |
| 430 // Create a native representation of the stream. | 385 // Create a native representation of the stream. |
| 431 if (request_succeeded) { | 386 if (request_succeeded) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 if (!stream->audio_tracks() || stream->audio_tracks()->count() == 0) | 553 if (!stream->audio_tracks() || stream->audio_tracks()->count() == 0) |
| 599 return NULL; | 554 return NULL; |
| 600 | 555 |
| 601 DVLOG(1) << "MediaStreamImpl::CreateRemoteAudioRenderer label:" | 556 DVLOG(1) << "MediaStreamImpl::CreateRemoteAudioRenderer label:" |
| 602 << stream->label(); | 557 << stream->label(); |
| 603 | 558 |
| 604 return new WebRtcAudioRenderer(RenderViewObserver::routing_id()); | 559 return new WebRtcAudioRenderer(RenderViewObserver::routing_id()); |
| 605 } | 560 } |
| 606 | 561 |
| 607 scoped_refptr<WebRtcLocalAudioRenderer> | 562 scoped_refptr<WebRtcLocalAudioRenderer> |
| 608 MediaStreamImpl::CreateLocalAudioRenderer(int session_id) { | 563 MediaStreamImpl::CreateLocalAudioRenderer( |
| 609 // Ensure that the existing capturer reads data from the selected microphone. | 564 webrtc::MediaStreamInterface* stream) { |
| 565 if (!stream->audio_tracks() || stream->audio_tracks()->count() == 0) |
| 566 return NULL; |
| 567 |
| 568 DVLOG(1) << "MediaStreamImpl::CreateLocalAudioRenderer label:" |
| 569 << stream->label(); |
| 570 |
| 610 scoped_refptr<WebRtcAudioCapturer> source = | 571 scoped_refptr<WebRtcAudioCapturer> source = |
| 611 dependency_factory_->GetWebRtcAudioDevice()->capturer(); | 572 dependency_factory_->GetWebRtcAudioDevice()->capturer(); |
| 612 if (!source) { | 573 if (!source) { |
| 613 // The WebRtcAudioCapturer instance can be NULL e.g. if an unsupported | |
| 614 // sample rate is used. | |
| 615 // TODO(henrika): extend support of capture sample rates. | |
| 616 return NULL; | 574 return NULL; |
| 617 } | 575 } |
| 618 | 576 |
| 619 if (session_id != -1) | |
| 620 source->SetDevice(session_id); | |
| 621 | |
| 622 // Create a new WebRtcLocalAudioRenderer instance and connect it to the | 577 // Create a new WebRtcLocalAudioRenderer instance and connect it to the |
| 623 // existing WebRtcAudioCapturer so that the renderer can use it as source. | 578 // existing WebRtcAudioCapturer so that the renderer can use it as source. |
| 624 return new WebRtcLocalAudioRenderer(source, RenderViewObserver::routing_id()); | 579 return new WebRtcLocalAudioRenderer(source, RenderViewObserver::routing_id()); |
| 625 } | 580 } |
| 626 | 581 |
| 627 MediaStreamSourceExtraData::MediaStreamSourceExtraData( | 582 MediaStreamSourceExtraData::MediaStreamSourceExtraData( |
| 628 const StreamDeviceInfo& device_info) | 583 const StreamDeviceInfo& device_info) |
| 629 : device_info_(device_info) { | 584 : device_info_(device_info) { |
| 630 } | 585 } |
| 631 | 586 |
| 587 MediaStreamSourceExtraData::MediaStreamSourceExtraData( |
| 588 media::AudioCapturerSource* source) |
| 589 : audio_source_(source) { |
| 590 } |
| 591 |
| 632 MediaStreamSourceExtraData::~MediaStreamSourceExtraData() {} | 592 MediaStreamSourceExtraData::~MediaStreamSourceExtraData() {} |
| 633 | 593 |
| 634 MediaStreamExtraData::MediaStreamExtraData( | 594 MediaStreamExtraData::MediaStreamExtraData( |
| 635 webrtc::MediaStreamInterface* remote_stream) | 595 webrtc::MediaStreamInterface* remote_stream) |
| 636 : remote_stream_(remote_stream) { | 596 : remote_stream_(remote_stream) { |
| 637 } | 597 } |
| 638 | 598 |
| 639 MediaStreamExtraData::MediaStreamExtraData( | 599 MediaStreamExtraData::MediaStreamExtraData( |
| 640 webrtc::LocalMediaStreamInterface* local_stream) | 600 webrtc::LocalMediaStreamInterface* local_stream) |
| 641 : local_stream_(local_stream) { | 601 : local_stream_(local_stream) { |
| 642 } | 602 } |
| 643 | 603 |
| 644 MediaStreamExtraData::~MediaStreamExtraData() { | 604 MediaStreamExtraData::~MediaStreamExtraData() { |
| 645 } | 605 } |
| 646 | 606 |
| 647 void MediaStreamExtraData::SetLocalStreamStopCallback( | 607 void MediaStreamExtraData::SetLocalStreamStopCallback( |
| 648 const StreamStopCallback& stop_callback) { | 608 const StreamStopCallback& stop_callback) { |
| 649 stream_stop_callback_ = stop_callback; | 609 stream_stop_callback_ = stop_callback; |
| 650 } | 610 } |
| 651 | 611 |
| 652 void MediaStreamExtraData::OnLocalStreamStop() { | 612 void MediaStreamExtraData::OnLocalStreamStop() { |
| 653 if (!stream_stop_callback_.is_null()) | 613 if (!stream_stop_callback_.is_null()) |
| 654 stream_stop_callback_.Run(local_stream_->label()); | 614 stream_stop_callback_.Run(local_stream_->label()); |
| 655 } | 615 } |
| 656 | 616 |
| 657 } // namespace content | 617 } // namespace content |
| OLD | NEW |