OLD | NEW |
---|---|
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 15 matching lines...) Expand all Loading... | |
26 */ | 26 */ |
27 | 27 |
28 #include "talk/app/webrtc/peerconnection.h" | 28 #include "talk/app/webrtc/peerconnection.h" |
29 | 29 |
30 #include <vector> | 30 #include <vector> |
31 | 31 |
32 #include "talk/app/webrtc/dtmfsender.h" | 32 #include "talk/app/webrtc/dtmfsender.h" |
33 #include "talk/app/webrtc/jsepicecandidate.h" | 33 #include "talk/app/webrtc/jsepicecandidate.h" |
34 #include "talk/app/webrtc/jsepsessiondescription.h" | 34 #include "talk/app/webrtc/jsepsessiondescription.h" |
35 #include "talk/app/webrtc/mediaconstraintsinterface.h" | 35 #include "talk/app/webrtc/mediaconstraintsinterface.h" |
36 #include "talk/app/webrtc/mediastreamhandler.h" | |
37 #include "talk/app/webrtc/streamcollection.h" | 36 #include "talk/app/webrtc/streamcollection.h" |
38 #include "webrtc/p2p/client/basicportallocator.h" | 37 #include "webrtc/p2p/client/basicportallocator.h" |
39 #include "talk/session/media/channelmanager.h" | 38 #include "talk/session/media/channelmanager.h" |
40 #include "webrtc/base/logging.h" | 39 #include "webrtc/base/logging.h" |
41 #include "webrtc/base/stringencode.h" | 40 #include "webrtc/base/stringencode.h" |
42 #include "webrtc/system_wrappers/interface/field_trial.h" | 41 #include "webrtc/system_wrappers/interface/field_trial.h" |
43 | 42 |
44 namespace { | 43 namespace { |
45 | 44 |
46 using webrtc::PeerConnectionInterface; | 45 using webrtc::PeerConnectionInterface; |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 observer_(NULL), | 331 observer_(NULL), |
333 uma_observer_(NULL), | 332 uma_observer_(NULL), |
334 signaling_state_(kStable), | 333 signaling_state_(kStable), |
335 ice_state_(kIceNew), | 334 ice_state_(kIceNew), |
336 ice_connection_state_(kIceConnectionNew), | 335 ice_connection_state_(kIceConnectionNew), |
337 ice_gathering_state_(kIceGatheringNew) { | 336 ice_gathering_state_(kIceGatheringNew) { |
338 } | 337 } |
339 | 338 |
340 PeerConnection::~PeerConnection() { | 339 PeerConnection::~PeerConnection() { |
341 ASSERT(signaling_thread()->IsCurrent()); | 340 ASSERT(signaling_thread()->IsCurrent()); |
342 if (mediastream_signaling_) | 341 if (mediastream_signaling_) { |
343 mediastream_signaling_->TearDown(); | 342 mediastream_signaling_->TearDown(); |
344 if (stream_handler_container_) | 343 } |
345 stream_handler_container_->TearDown(); | 344 // Need to detach RTP senders/receivers from WebRtcSession, |
345 // since it's about to be destroyed. | |
346 for (const auto& sender : rtp_senders_) { | |
347 sender->DetachFromProvider(); | |
348 } | |
349 for (const auto& receiver : rtp_receivers_) { | |
350 receiver->DetachFromProvider(); | |
351 } | |
346 } | 352 } |
347 | 353 |
348 bool PeerConnection::Initialize( | 354 bool PeerConnection::Initialize( |
349 const PeerConnectionInterface::RTCConfiguration& configuration, | 355 const PeerConnectionInterface::RTCConfiguration& configuration, |
350 const MediaConstraintsInterface* constraints, | 356 const MediaConstraintsInterface* constraints, |
351 PortAllocatorFactoryInterface* allocator_factory, | 357 PortAllocatorFactoryInterface* allocator_factory, |
352 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, | 358 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, |
353 PeerConnectionObserver* observer) { | 359 PeerConnectionObserver* observer) { |
354 ASSERT(observer != NULL); | 360 ASSERT(observer != NULL); |
355 if (!observer) | 361 if (!observer) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
392 port_allocator_->set_step_delay(cricket::kMinimumStepDelay); | 398 port_allocator_->set_step_delay(cricket::kMinimumStepDelay); |
393 | 399 |
394 mediastream_signaling_.reset(new MediaStreamSignaling( | 400 mediastream_signaling_.reset(new MediaStreamSignaling( |
395 factory_->signaling_thread(), this, factory_->channel_manager())); | 401 factory_->signaling_thread(), this, factory_->channel_manager())); |
396 | 402 |
397 session_.reset(new WebRtcSession(factory_->channel_manager(), | 403 session_.reset(new WebRtcSession(factory_->channel_manager(), |
398 factory_->signaling_thread(), | 404 factory_->signaling_thread(), |
399 factory_->worker_thread(), | 405 factory_->worker_thread(), |
400 port_allocator_.get(), | 406 port_allocator_.get(), |
401 mediastream_signaling_.get())); | 407 mediastream_signaling_.get())); |
402 stream_handler_container_.reset(new MediaStreamHandlerContainer( | |
403 session_.get(), session_.get())); | |
404 stats_.reset(new StatsCollector(session_.get())); | 408 stats_.reset(new StatsCollector(session_.get())); |
405 | 409 |
406 // Initialize the WebRtcSession. It creates transport channels etc. | 410 // Initialize the WebRtcSession. It creates transport channels etc. |
407 if (!session_->Initialize(factory_->options(), constraints, | 411 if (!session_->Initialize(factory_->options(), constraints, |
408 dtls_identity_store.Pass(), configuration)) | 412 dtls_identity_store.Pass(), configuration)) |
409 return false; | 413 return false; |
410 | 414 |
411 // Register PeerConnection as receiver of local ice candidates. | 415 // Register PeerConnection as receiver of local ice candidates. |
412 // All the callbacks will be posted to the application from PeerConnection. | 416 // All the callbacks will be posted to the application from PeerConnection. |
413 session_->RegisterIceObserver(this); | 417 session_->RegisterIceObserver(this); |
414 session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange); | 418 session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange); |
415 return true; | 419 return true; |
416 } | 420 } |
417 | 421 |
418 rtc::scoped_refptr<StreamCollectionInterface> | 422 rtc::scoped_refptr<StreamCollectionInterface> |
419 PeerConnection::local_streams() { | 423 PeerConnection::local_streams() { |
420 return mediastream_signaling_->local_streams(); | 424 return mediastream_signaling_->local_streams(); |
421 } | 425 } |
422 | 426 |
423 rtc::scoped_refptr<StreamCollectionInterface> | 427 rtc::scoped_refptr<StreamCollectionInterface> |
424 PeerConnection::remote_streams() { | 428 PeerConnection::remote_streams() { |
425 return mediastream_signaling_->remote_streams(); | 429 return mediastream_signaling_->remote_streams(); |
426 } | 430 } |
427 | 431 |
432 // TODO(deadbeef): Create RtpSenders immediately here, even if local | |
433 // description hasn't yet been set. | |
428 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { | 434 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { |
429 if (IsClosed()) { | 435 if (IsClosed()) { |
430 return false; | 436 return false; |
431 } | 437 } |
432 if (!CanAddLocalMediaStream(mediastream_signaling_->local_streams(), | 438 if (!CanAddLocalMediaStream(mediastream_signaling_->local_streams(), |
433 local_stream)) | 439 local_stream)) |
434 return false; | 440 return false; |
435 | 441 |
436 if (!mediastream_signaling_->AddLocalStream(local_stream)) { | 442 if (!mediastream_signaling_->AddLocalStream(local_stream)) { |
437 return false; | 443 return false; |
(...skipping 24 matching lines...) Expand all Loading... | |
462 | 468 |
463 rtc::scoped_refptr<DtmfSenderInterface> sender( | 469 rtc::scoped_refptr<DtmfSenderInterface> sender( |
464 DtmfSender::Create(track, signaling_thread(), session_.get())); | 470 DtmfSender::Create(track, signaling_thread(), session_.get())); |
465 if (!sender.get()) { | 471 if (!sender.get()) { |
466 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; | 472 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; |
467 return NULL; | 473 return NULL; |
468 } | 474 } |
469 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); | 475 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); |
470 } | 476 } |
471 | 477 |
478 RtpSenderRefptrs PeerConnection::GetSenders() const { | |
479 RtpSenderRefptrs senders; | |
480 for (const auto& sender : rtp_senders_) { | |
481 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get())); | |
482 } | |
pthatcher1
2015/09/24 06:32:29
Why do we still have proxies here?
Can't we jus
Taylor Brandstetter
2015/09/24 20:54:20
We still need to return an object that does thread
pthatcher1
2015/09/24 21:18:34
OK, I get it now. Thanks.
| |
483 return senders; | |
484 } | |
485 | |
486 RtpReceiverRefptrs PeerConnection::GetReceivers() const { | |
487 RtpReceiverRefptrs receivers; | |
488 for (const auto& receiver : rtp_receivers_) { | |
489 receivers.push_back( | |
490 RtpReceiverProxy::Create(signaling_thread(), receiver.get())); | |
491 } | |
492 return receivers; | |
493 } | |
494 | |
472 bool PeerConnection::GetStats(StatsObserver* observer, | 495 bool PeerConnection::GetStats(StatsObserver* observer, |
473 MediaStreamTrackInterface* track, | 496 MediaStreamTrackInterface* track, |
474 StatsOutputLevel level) { | 497 StatsOutputLevel level) { |
475 ASSERT(signaling_thread()->IsCurrent()); | 498 ASSERT(signaling_thread()->IsCurrent()); |
476 if (!VERIFY(observer != NULL)) { | 499 if (!VERIFY(observer != NULL)) { |
477 LOG(LS_ERROR) << "GetStats - observer is NULL."; | 500 LOG(LS_ERROR) << "GetStats - observer is NULL."; |
478 return false; | 501 return false; |
479 } | 502 } |
480 | 503 |
481 stats_->UpdateStats(level); | 504 stats_->UpdateStats(level); |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
799 break; | 822 break; |
800 } | 823 } |
801 } | 824 } |
802 | 825 |
803 void PeerConnection::OnAddRemoteStream(MediaStreamInterface* stream) { | 826 void PeerConnection::OnAddRemoteStream(MediaStreamInterface* stream) { |
804 stats_->AddStream(stream); | 827 stats_->AddStream(stream); |
805 observer_->OnAddStream(stream); | 828 observer_->OnAddStream(stream); |
806 } | 829 } |
807 | 830 |
808 void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) { | 831 void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) { |
809 stream_handler_container_->RemoveRemoteStream(stream); | |
810 observer_->OnRemoveStream(stream); | 832 observer_->OnRemoveStream(stream); |
811 } | 833 } |
812 | 834 |
813 void PeerConnection::OnAddDataChannel(DataChannelInterface* data_channel) { | 835 void PeerConnection::OnAddDataChannel(DataChannelInterface* data_channel) { |
814 observer_->OnDataChannel(DataChannelProxy::Create(signaling_thread(), | 836 observer_->OnDataChannel(DataChannelProxy::Create(signaling_thread(), |
815 data_channel)); | 837 data_channel)); |
816 } | 838 } |
817 | 839 |
818 void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream, | 840 void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream, |
819 AudioTrackInterface* audio_track, | 841 AudioTrackInterface* audio_track, |
820 uint32 ssrc) { | 842 uint32 ssrc) { |
821 stream_handler_container_->AddRemoteAudioTrack(stream, audio_track, ssrc); | 843 rtp_receivers_.push_back( |
844 new AudioRtpReceiver(audio_track, ssrc, session_.get())); | |
822 } | 845 } |
823 | 846 |
824 void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream, | 847 void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream, |
825 VideoTrackInterface* video_track, | 848 VideoTrackInterface* video_track, |
826 uint32 ssrc) { | 849 uint32 ssrc) { |
827 stream_handler_container_->AddRemoteVideoTrack(stream, video_track, ssrc); | 850 rtp_receivers_.push_back( |
851 new VideoRtpReceiver(video_track, ssrc, session_.get())); | |
828 } | 852 } |
829 | 853 |
854 // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote | |
855 // description. | |
830 void PeerConnection::OnRemoveRemoteAudioTrack( | 856 void PeerConnection::OnRemoveRemoteAudioTrack( |
831 MediaStreamInterface* stream, | 857 MediaStreamInterface* stream, |
832 AudioTrackInterface* audio_track) { | 858 AudioTrackInterface* audio_track) { |
833 stream_handler_container_->RemoveRemoteTrack(stream, audio_track); | 859 auto it = FindRtpReceiverForTrack(audio_track); |
860 if (it == rtp_receivers_.end()) { | |
861 LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id() | |
862 << " doesn't exist."; | |
863 } else { | |
864 (*it)->DetachFromProvider(); | |
pthatcher1
2015/09/24 06:32:29
Nit: our usual style is it.second->Foo() rather th
Taylor Brandstetter
2015/09/24 20:54:20
But this isn't an iterator to a pair of pointers,
pthatcher1
2015/09/24 21:18:34
Oh, duh :).
| |
865 rtp_receivers_.erase(it); | |
866 } | |
834 } | 867 } |
835 | 868 |
836 void PeerConnection::OnRemoveRemoteVideoTrack( | 869 void PeerConnection::OnRemoveRemoteVideoTrack( |
837 MediaStreamInterface* stream, | 870 MediaStreamInterface* stream, |
838 VideoTrackInterface* video_track) { | 871 VideoTrackInterface* video_track) { |
839 stream_handler_container_->RemoveRemoteTrack(stream, video_track); | 872 auto it = FindRtpReceiverForTrack(video_track); |
873 if (it == rtp_receivers_.end()) { | |
874 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() | |
875 << " doesn't exist."; | |
876 } else { | |
877 (*it)->DetachFromProvider(); | |
878 rtp_receivers_.erase(it); | |
879 } | |
840 } | 880 } |
881 | |
841 void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream, | 882 void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream, |
842 AudioTrackInterface* audio_track, | 883 AudioTrackInterface* audio_track, |
843 uint32 ssrc) { | 884 uint32 ssrc) { |
844 stream_handler_container_->AddLocalAudioTrack(stream, audio_track, ssrc); | 885 rtp_senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get())); |
845 stats_->AddLocalAudioTrack(audio_track, ssrc); | 886 stats_->AddLocalAudioTrack(audio_track, ssrc); |
846 } | 887 } |
888 | |
847 void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream, | 889 void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream, |
848 VideoTrackInterface* video_track, | 890 VideoTrackInterface* video_track, |
849 uint32 ssrc) { | 891 uint32 ssrc) { |
850 stream_handler_container_->AddLocalVideoTrack(stream, video_track, ssrc); | 892 rtp_senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get())); |
851 } | 893 } |
852 | 894 |
895 // TODO(deadbeef): Keep RtpSenders around even if track goes away in local | |
896 // description. | |
853 void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream, | 897 void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream, |
854 AudioTrackInterface* audio_track, | 898 AudioTrackInterface* audio_track, |
855 uint32 ssrc) { | 899 uint32 ssrc) { |
856 stream_handler_container_->RemoveLocalTrack(stream, audio_track); | 900 auto it = FindRtpSenderForTrack(audio_track); |
901 if (it == rtp_senders_.end()) { | |
902 LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id() | |
903 << " doesn't exist."; | |
904 return; | |
905 } else { | |
906 (*it)->DetachFromProvider(); | |
907 rtp_senders_.erase(it); | |
908 } | |
857 stats_->RemoveLocalAudioTrack(audio_track, ssrc); | 909 stats_->RemoveLocalAudioTrack(audio_track, ssrc); |
858 } | 910 } |
859 | 911 |
860 void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream, | 912 void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream, |
861 VideoTrackInterface* video_track) { | 913 VideoTrackInterface* video_track) { |
862 stream_handler_container_->RemoveLocalTrack(stream, video_track); | 914 auto it = FindRtpSenderForTrack(video_track); |
915 if (it == rtp_senders_.end()) { | |
916 LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id() | |
917 << " doesn't exist."; | |
918 return; | |
919 } else { | |
920 (*it)->DetachFromProvider(); | |
921 rtp_senders_.erase(it); | |
922 } | |
863 } | 923 } |
864 | 924 |
865 void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) { | 925 void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) { |
866 stream_handler_container_->RemoveLocalStream(stream); | |
867 } | 926 } |
868 | 927 |
869 void PeerConnection::OnIceConnectionChange( | 928 void PeerConnection::OnIceConnectionChange( |
870 PeerConnectionInterface::IceConnectionState new_state) { | 929 PeerConnectionInterface::IceConnectionState new_state) { |
871 ASSERT(signaling_thread()->IsCurrent()); | 930 ASSERT(signaling_thread()->IsCurrent()); |
872 ice_connection_state_ = new_state; | 931 ice_connection_state_ = new_state; |
873 observer_->OnIceConnectionChange(ice_connection_state_); | 932 observer_->OnIceConnectionChange(ice_connection_state_); |
874 } | 933 } |
875 | 934 |
876 void PeerConnection::OnIceGatheringChange( | 935 void PeerConnection::OnIceGatheringChange( |
(...skipping 29 matching lines...) Expand all Loading... | |
906 observer_->OnIceConnectionChange(ice_connection_state_); | 965 observer_->OnIceConnectionChange(ice_connection_state_); |
907 if (ice_gathering_state_ != kIceGatheringComplete) { | 966 if (ice_gathering_state_ != kIceGatheringComplete) { |
908 ice_gathering_state_ = kIceGatheringComplete; | 967 ice_gathering_state_ = kIceGatheringComplete; |
909 observer_->OnIceGatheringChange(ice_gathering_state_); | 968 observer_->OnIceGatheringChange(ice_gathering_state_); |
910 } | 969 } |
911 } | 970 } |
912 observer_->OnSignalingChange(signaling_state_); | 971 observer_->OnSignalingChange(signaling_state_); |
913 observer_->OnStateChange(PeerConnectionObserver::kSignalingState); | 972 observer_->OnStateChange(PeerConnectionObserver::kSignalingState); |
914 } | 973 } |
915 | 974 |
975 PeerConnection::BaseRtpSenderRefptrs::iterator | |
976 PeerConnection::FindRtpSenderForTrack(MediaStreamTrackInterface* track) { | |
977 return std::find_if(rtp_senders_.begin(), rtp_senders_.end(), | |
978 [track](const rtc::scoped_refptr<BaseRtpSender>& sender) { | |
979 return sender->track() == track; | |
980 }); | |
981 } | |
982 PeerConnection::BaseRtpReceiverRefptrs::iterator | |
983 PeerConnection::FindRtpReceiverForTrack(MediaStreamTrackInterface* track) { | |
984 return std::find_if( | |
985 rtp_receivers_.begin(), rtp_receivers_.end(), | |
986 [track](const rtc::scoped_refptr<BaseRtpReceiver>& receiver) { | |
987 return receiver->track() == track; | |
988 }); | |
989 } | |
990 | |
916 } // namespace webrtc | 991 } // namespace webrtc |
OLD | NEW |