Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/webrtc/peer_connection_dependency_factory.h" | 5 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 rtc::NetworkManager* network_manager_; | 162 rtc::NetworkManager* network_manager_; |
| 163 rtc::PacketSocketFactory* socket_factory_; | 163 rtc::PacketSocketFactory* socket_factory_; |
| 164 }; | 164 }; |
| 165 | 165 |
| 166 PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( | 166 PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( |
| 167 P2PSocketDispatcher* p2p_socket_dispatcher) | 167 P2PSocketDispatcher* p2p_socket_dispatcher) |
| 168 : network_manager_(NULL), | 168 : network_manager_(NULL), |
| 169 p2p_socket_dispatcher_(p2p_socket_dispatcher), | 169 p2p_socket_dispatcher_(p2p_socket_dispatcher), |
| 170 signaling_thread_(NULL), | 170 signaling_thread_(NULL), |
| 171 worker_thread_(NULL), | 171 worker_thread_(NULL), |
| 172 chrome_signaling_thread_("Chrome_libJingle_Signaling"), | |
| 172 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { | 173 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { |
| 173 } | 174 } |
| 174 | 175 |
| 175 PeerConnectionDependencyFactory::~PeerConnectionDependencyFactory() { | 176 PeerConnectionDependencyFactory::~PeerConnectionDependencyFactory() { |
| 176 CleanupPeerConnectionFactory(); | 177 CleanupPeerConnectionFactory(); |
| 177 if (aec_dump_message_filter_.get()) | 178 if (aec_dump_message_filter_.get()) |
| 178 aec_dump_message_filter_->RemoveDelegate(this); | 179 aec_dump_message_filter_->RemoveDelegate(this); |
| 179 } | 180 } |
| 180 | 181 |
| 181 blink::WebRTCPeerConnectionHandler* | 182 blink::WebRTCPeerConnectionHandler* |
| 182 PeerConnectionDependencyFactory::CreateRTCPeerConnectionHandler( | 183 PeerConnectionDependencyFactory::CreateRTCPeerConnectionHandler( |
| 183 blink::WebRTCPeerConnectionHandlerClient* client) { | 184 blink::WebRTCPeerConnectionHandlerClient* client) { |
| 184 // Save histogram data so we can see how much PeerConnetion is used. | 185 // Save histogram data so we can see how much PeerConnetion is used. |
| 185 // The histogram counts the number of calls to the JS API | 186 // The histogram counts the number of calls to the JS API |
| 186 // webKitRTCPeerConnection. | 187 // webKitRTCPeerConnection. |
| 187 UpdateWebRTCMethodCount(WEBKIT_RTC_PEER_CONNECTION); | 188 UpdateWebRTCMethodCount(WEBKIT_RTC_PEER_CONNECTION); |
| 188 | 189 |
| 189 return new RTCPeerConnectionHandler(client, this); | 190 return new RTCPeerConnectionHandler(client, this, GetWebRtcSignalingThread()); |
| 190 } | 191 } |
| 191 | 192 |
| 192 bool PeerConnectionDependencyFactory::InitializeMediaStreamAudioSource( | 193 bool PeerConnectionDependencyFactory::InitializeMediaStreamAudioSource( |
| 193 int render_view_id, | 194 int render_view_id, |
| 194 const blink::WebMediaConstraints& audio_constraints, | 195 const blink::WebMediaConstraints& audio_constraints, |
| 195 MediaStreamAudioSource* source_data) { | 196 MediaStreamAudioSource* source_data) { |
| 196 DVLOG(1) << "InitializeMediaStreamAudioSources()"; | 197 DVLOG(1) << "InitializeMediaStreamAudioSources()"; |
| 197 | 198 |
| 198 // Do additional source initialization if the audio source is a valid | 199 // Do additional source initialization if the audio source is a valid |
| 199 // microphone or tab audio. | 200 // microphone or tab audio. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 CHECK(pc_factory_.get()); | 267 CHECK(pc_factory_.get()); |
| 267 return pc_factory_; | 268 return pc_factory_; |
| 268 } | 269 } |
| 269 | 270 |
| 270 void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { | 271 void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { |
| 271 DCHECK(!pc_factory_.get()); | 272 DCHECK(!pc_factory_.get()); |
| 272 DCHECK(!signaling_thread_); | 273 DCHECK(!signaling_thread_); |
| 273 DCHECK(!worker_thread_); | 274 DCHECK(!worker_thread_); |
| 274 DCHECK(!network_manager_); | 275 DCHECK(!network_manager_); |
| 275 DCHECK(!socket_factory_); | 276 DCHECK(!socket_factory_); |
| 277 DCHECK(!chrome_signaling_thread_.IsRunning()); | |
| 276 DCHECK(!chrome_worker_thread_.IsRunning()); | 278 DCHECK(!chrome_worker_thread_.IsRunning()); |
| 277 | 279 |
| 278 DVLOG(1) << "PeerConnectionDependencyFactory::CreatePeerConnectionFactory()"; | 280 DVLOG(1) << "PeerConnectionDependencyFactory::CreatePeerConnectionFactory()"; |
| 279 | 281 |
| 282 // To allow sending to the signaling/worker threads. | |
| 280 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); | 283 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
| 281 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | 284 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| 282 signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); | |
| 283 CHECK(signaling_thread_); | |
| 284 | 285 |
| 286 CHECK(chrome_signaling_thread_.Start()); | |
| 285 CHECK(chrome_worker_thread_.Start()); | 287 CHECK(chrome_worker_thread_.Start()); |
| 286 | 288 |
| 287 base::WaitableEvent start_worker_event(true, false); | 289 base::WaitableEvent start_worker_event(true, false); |
| 288 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 290 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 289 &PeerConnectionDependencyFactory::InitializeWorkerThread, | 291 &PeerConnectionDependencyFactory::InitializeWorkerThread, |
| 290 base::Unretained(this), | 292 base::Unretained(this), |
| 291 &worker_thread_, | 293 &worker_thread_, |
| 292 &start_worker_event)); | 294 &start_worker_event)); |
| 293 start_worker_event.Wait(); | |
| 294 CHECK(worker_thread_); | |
| 295 | 295 |
| 296 base::WaitableEvent create_network_manager_event(true, false); | 296 base::WaitableEvent create_network_manager_event(true, false); |
| 297 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 297 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 298 &PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnWorkerThread, | 298 &PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnWorkerThread, |
| 299 base::Unretained(this), | 299 base::Unretained(this), |
| 300 &create_network_manager_event)); | 300 &create_network_manager_event)); |
| 301 | |
| 302 start_worker_event.Wait(); | |
| 301 create_network_manager_event.Wait(); | 303 create_network_manager_event.Wait(); |
| 302 | 304 |
| 303 socket_factory_.reset( | 305 CHECK(worker_thread_); |
| 304 new IpcPacketSocketFactory(p2p_socket_dispatcher_.get())); | |
| 305 | 306 |
| 306 // Init SSL, which will be needed by PeerConnection. | 307 // Init SSL, which will be needed by PeerConnection. |
| 307 #if defined(USE_OPENSSL) | 308 #if defined(USE_OPENSSL) |
| 308 if (!rtc::InitializeSSL()) { | 309 if (!rtc::InitializeSSL()) { |
| 309 LOG(ERROR) << "Failed on InitializeSSL."; | 310 LOG(ERROR) << "Failed on InitializeSSL."; |
| 310 NOTREACHED(); | 311 NOTREACHED(); |
| 311 return; | 312 return; |
| 312 } | 313 } |
| 313 #else | 314 #else |
| 314 // TODO(ronghuawu): Replace this call with InitializeSSL. | 315 // TODO(ronghuawu): Replace this call with InitializeSSL. |
| 315 net::EnsureNSSSSLInit(); | 316 net::EnsureNSSSSLInit(); |
| 316 #endif | 317 #endif |
| 317 | 318 |
| 319 base::WaitableEvent start_signaling_event(true, false); | |
| 320 chrome_signaling_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | |
| 321 &PeerConnectionDependencyFactory::InitializeSignalingThread, | |
| 322 base::Unretained(this), | |
| 323 RenderThreadImpl::current()->GetGpuFactories(), | |
| 324 &start_signaling_event)); | |
| 325 | |
| 326 // TODO(xians): Remove the following code after kDisableAudioTrackProcessing | |
| 327 // is removed. | |
| 328 if (!MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()) { | |
|
no longer working on chromium
2014/10/30 11:55:14
just remove line 328-335
:) or you probably should
tommi (sloooow) - chröme
2014/10/30 20:37:36
Good point. Looked at your cl and lgtm-ed it.
| |
| 329 aec_dump_message_filter_ = AecDumpMessageFilter::Get(); | |
| 330 // In unit tests not creating a message filter, |aec_dump_message_filter_| | |
| 331 // will be NULL. We can just ignore that. Other unit tests and browser tests | |
| 332 // ensure that we do get the filter when we should. | |
| 333 if (aec_dump_message_filter_.get()) | |
| 334 aec_dump_message_filter_->AddDelegate(this); | |
| 335 } | |
| 336 | |
| 337 start_signaling_event.Wait(); | |
| 338 CHECK(signaling_thread_); | |
| 339 } | |
| 340 | |
| 341 void PeerConnectionDependencyFactory::InitializeSignalingThread( | |
| 342 const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories, | |
| 343 base::WaitableEvent* event) { | |
| 344 DCHECK(chrome_signaling_thread_.task_runner()->BelongsToCurrentThread()); | |
| 345 DCHECK(worker_thread_); | |
| 346 DCHECK(p2p_socket_dispatcher_.get()); | |
| 347 | |
| 348 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); | |
| 349 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | |
| 350 signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); | |
| 351 | |
| 352 EnsureWebRtcAudioDeviceImpl(); | |
| 353 | |
| 354 socket_factory_.reset( | |
| 355 new IpcPacketSocketFactory(p2p_socket_dispatcher_.get())); | |
| 356 | |
| 318 scoped_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory; | 357 scoped_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory; |
| 319 scoped_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory; | 358 scoped_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory; |
| 320 | 359 |
| 321 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 360 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| 322 scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories = | 361 if (gpu_factories.get()) { |
| 323 RenderThreadImpl::current()->GetGpuFactories(); | 362 if (!cmd_line->HasSwitch(switches::kDisableWebRtcHWDecoding)) |
| 324 if (!cmd_line->HasSwitch(switches::kDisableWebRtcHWDecoding)) { | |
| 325 if (gpu_factories.get()) | |
| 326 decoder_factory.reset(new RTCVideoDecoderFactory(gpu_factories)); | 363 decoder_factory.reset(new RTCVideoDecoderFactory(gpu_factories)); |
| 327 } | |
| 328 | 364 |
| 329 if (!cmd_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) { | 365 if (!cmd_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) |
| 330 if (gpu_factories.get()) | |
| 331 encoder_factory.reset(new RTCVideoEncoderFactory(gpu_factories)); | 366 encoder_factory.reset(new RTCVideoEncoderFactory(gpu_factories)); |
| 332 } | 367 } |
| 333 | 368 |
| 334 #if defined(OS_ANDROID) | 369 #if defined(OS_ANDROID) |
| 335 if (!media::MediaCodecBridge::SupportsSetParameters()) | 370 if (!media::MediaCodecBridge::SupportsSetParameters()) |
| 336 encoder_factory.reset(); | 371 encoder_factory.reset(); |
| 337 #endif | 372 #endif |
| 338 | 373 |
| 339 EnsureWebRtcAudioDeviceImpl(); | 374 pc_factory_ = webrtc::CreatePeerConnectionFactory( |
| 375 worker_thread_, signaling_thread_, audio_device_.get(), | |
| 376 encoder_factory.release(), decoder_factory.release()); | |
| 377 CHECK(pc_factory_.get()); | |
| 340 | 378 |
| 341 scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory( | |
| 342 webrtc::CreatePeerConnectionFactory(worker_thread_, | |
| 343 signaling_thread_, | |
| 344 audio_device_.get(), | |
| 345 encoder_factory.release(), | |
| 346 decoder_factory.release())); | |
| 347 CHECK(factory.get()); | |
| 348 | |
| 349 pc_factory_ = factory; | |
| 350 webrtc::PeerConnectionFactoryInterface::Options factory_options; | 379 webrtc::PeerConnectionFactoryInterface::Options factory_options; |
| 351 factory_options.disable_sctp_data_channels = false; | 380 factory_options.disable_sctp_data_channels = false; |
| 352 factory_options.disable_encryption = | 381 factory_options.disable_encryption = |
| 353 cmd_line->HasSwitch(switches::kDisableWebRtcEncryption); | 382 cmd_line->HasSwitch(switches::kDisableWebRtcEncryption); |
| 354 pc_factory_->SetOptions(factory_options); | 383 pc_factory_->SetOptions(factory_options); |
| 355 | 384 |
| 356 // TODO(xians): Remove the following code after kDisableAudioTrackProcessing | 385 event->Signal(); |
| 357 // is removed. | |
| 358 if (!MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()) { | |
| 359 aec_dump_message_filter_ = AecDumpMessageFilter::Get(); | |
| 360 // In unit tests not creating a message filter, |aec_dump_message_filter_| | |
| 361 // will be NULL. We can just ignore that. Other unit tests and browser tests | |
| 362 // ensure that we do get the filter when we should. | |
| 363 if (aec_dump_message_filter_.get()) | |
| 364 aec_dump_message_filter_->AddDelegate(this); | |
| 365 } | |
| 366 } | 386 } |
| 367 | 387 |
| 368 bool PeerConnectionDependencyFactory::PeerConnectionFactoryCreated() { | 388 bool PeerConnectionDependencyFactory::PeerConnectionFactoryCreated() { |
| 369 return pc_factory_.get() != NULL; | 389 return pc_factory_.get() != NULL; |
| 370 } | 390 } |
| 371 | 391 |
| 372 scoped_refptr<webrtc::PeerConnectionInterface> | 392 scoped_refptr<webrtc::PeerConnectionInterface> |
| 373 PeerConnectionDependencyFactory::CreatePeerConnection( | 393 PeerConnectionDependencyFactory::CreatePeerConnection( |
| 374 const webrtc::PeerConnectionInterface::RTCConfiguration& config, | 394 const webrtc::PeerConnectionInterface::RTCConfiguration& config, |
| 375 const webrtc::MediaConstraintsInterface* constraints, | 395 const webrtc::MediaConstraintsInterface* constraints, |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 DCHECK_GE(render_view_id, 0); | 613 DCHECK_GE(render_view_id, 0); |
| 594 | 614 |
| 595 EnsureWebRtcAudioDeviceImpl(); | 615 EnsureWebRtcAudioDeviceImpl(); |
| 596 DCHECK(GetWebRtcAudioDevice()); | 616 DCHECK(GetWebRtcAudioDevice()); |
| 597 return WebRtcAudioCapturer::CreateCapturer(render_view_id, device_info, | 617 return WebRtcAudioCapturer::CreateCapturer(render_view_id, device_info, |
| 598 constraints, | 618 constraints, |
| 599 GetWebRtcAudioDevice(), | 619 GetWebRtcAudioDevice(), |
| 600 audio_source); | 620 audio_source); |
| 601 } | 621 } |
| 602 | 622 |
| 603 void PeerConnectionDependencyFactory::AddNativeAudioTrackToBlinkTrack( | |
| 604 webrtc::MediaStreamTrackInterface* native_track, | |
| 605 const blink::WebMediaStreamTrack& webkit_track, | |
| 606 bool is_local_track) { | |
| 607 DCHECK(!webkit_track.isNull() && !webkit_track.extraData()); | |
| 608 DCHECK_EQ(blink::WebMediaStreamSource::TypeAudio, | |
| 609 webkit_track.source().type()); | |
| 610 blink::WebMediaStreamTrack track = webkit_track; | |
| 611 | |
| 612 DVLOG(1) << "AddNativeTrackToBlinkTrack() audio"; | |
| 613 track.setExtraData( | |
| 614 new MediaStreamTrack( | |
| 615 static_cast<webrtc::AudioTrackInterface*>(native_track), | |
| 616 is_local_track)); | |
| 617 } | |
| 618 | |
| 619 scoped_refptr<base::MessageLoopProxy> | 623 scoped_refptr<base::MessageLoopProxy> |
| 620 PeerConnectionDependencyFactory::GetWebRtcWorkerThread() const { | 624 PeerConnectionDependencyFactory::GetWebRtcWorkerThread() const { |
| 621 DCHECK(CalledOnValidThread()); | 625 DCHECK(CalledOnValidThread()); |
| 622 return chrome_worker_thread_.message_loop_proxy(); | 626 return chrome_worker_thread_.message_loop_proxy(); |
| 623 } | 627 } |
| 624 | 628 |
| 625 scoped_refptr<base::MessageLoopProxy> | 629 scoped_refptr<base::MessageLoopProxy> |
| 626 PeerConnectionDependencyFactory::GetWebRtcSignalingThread() const { | 630 PeerConnectionDependencyFactory::GetWebRtcSignalingThread() const { |
| 627 DCHECK(CalledOnValidThread()); | 631 DCHECK(CalledOnValidThread()); |
| 628 return RenderThreadImpl::current()->GetMessageLoop()->message_loop_proxy(); | 632 return chrome_signaling_thread_.message_loop_proxy(); |
| 629 } | 633 } |
| 630 | 634 |
| 631 void PeerConnectionDependencyFactory::OnAecDumpFile( | 635 void PeerConnectionDependencyFactory::OnAecDumpFile( |
| 632 const IPC::PlatformFileForTransit& file_handle) { | 636 const IPC::PlatformFileForTransit& file_handle) { |
| 633 DCHECK(CalledOnValidThread()); | 637 DCHECK(CalledOnValidThread()); |
| 634 DCHECK(!MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()); | 638 DCHECK(!MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()); |
| 635 DCHECK(PeerConnectionFactoryCreated()); | 639 DCHECK(PeerConnectionFactoryCreated()); |
| 636 | 640 |
| 637 base::File file = IPC::PlatformFileForTransitToFile(file_handle); | 641 base::File file = IPC::PlatformFileForTransitToFile(file_handle); |
| 638 DCHECK(file.IsValid()); | 642 DCHECK(file.IsValid()); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 655 } | 659 } |
| 656 | 660 |
| 657 void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() { | 661 void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() { |
| 658 if (audio_device_.get()) | 662 if (audio_device_.get()) |
| 659 return; | 663 return; |
| 660 | 664 |
| 661 audio_device_ = new WebRtcAudioDeviceImpl(); | 665 audio_device_ = new WebRtcAudioDeviceImpl(); |
| 662 } | 666 } |
| 663 | 667 |
| 664 } // namespace content | 668 } // namespace content |
| OLD | NEW |