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" | 36 #include "talk/app/webrtc/rtpreceiver.h" |
| 37 #include "talk/app/webrtc/rtpsender.h" |
37 #include "talk/app/webrtc/streamcollection.h" | 38 #include "talk/app/webrtc/streamcollection.h" |
38 #include "webrtc/p2p/client/basicportallocator.h" | 39 #include "webrtc/p2p/client/basicportallocator.h" |
39 #include "talk/session/media/channelmanager.h" | 40 #include "talk/session/media/channelmanager.h" |
40 #include "webrtc/base/logging.h" | 41 #include "webrtc/base/logging.h" |
41 #include "webrtc/base/stringencode.h" | 42 #include "webrtc/base/stringencode.h" |
42 #include "webrtc/system_wrappers/interface/field_trial.h" | 43 #include "webrtc/system_wrappers/interface/field_trial.h" |
43 | 44 |
44 namespace { | 45 namespace { |
45 | 46 |
46 using webrtc::PeerConnectionInterface; | 47 using webrtc::PeerConnectionInterface; |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 observer_(NULL), | 333 observer_(NULL), |
333 uma_observer_(NULL), | 334 uma_observer_(NULL), |
334 signaling_state_(kStable), | 335 signaling_state_(kStable), |
335 ice_state_(kIceNew), | 336 ice_state_(kIceNew), |
336 ice_connection_state_(kIceConnectionNew), | 337 ice_connection_state_(kIceConnectionNew), |
337 ice_gathering_state_(kIceGatheringNew) { | 338 ice_gathering_state_(kIceGatheringNew) { |
338 } | 339 } |
339 | 340 |
340 PeerConnection::~PeerConnection() { | 341 PeerConnection::~PeerConnection() { |
341 ASSERT(signaling_thread()->IsCurrent()); | 342 ASSERT(signaling_thread()->IsCurrent()); |
342 if (mediastream_signaling_) | 343 if (mediastream_signaling_) { |
343 mediastream_signaling_->TearDown(); | 344 mediastream_signaling_->TearDown(); |
344 if (stream_handler_container_) | 345 } |
345 stream_handler_container_->TearDown(); | 346 // Need to detach RTP senders/receivers from WebRtcSession, |
| 347 // since it's about to be destroyed. |
| 348 for (const auto& sender : senders_) { |
| 349 sender->Stop(); |
| 350 } |
| 351 for (const auto& receiver : receivers_) { |
| 352 receiver->Stop(); |
| 353 } |
346 } | 354 } |
347 | 355 |
348 bool PeerConnection::Initialize( | 356 bool PeerConnection::Initialize( |
349 const PeerConnectionInterface::RTCConfiguration& configuration, | 357 const PeerConnectionInterface::RTCConfiguration& configuration, |
350 const MediaConstraintsInterface* constraints, | 358 const MediaConstraintsInterface* constraints, |
351 PortAllocatorFactoryInterface* allocator_factory, | 359 PortAllocatorFactoryInterface* allocator_factory, |
352 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, | 360 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, |
353 PeerConnectionObserver* observer) { | 361 PeerConnectionObserver* observer) { |
354 ASSERT(observer != NULL); | 362 ASSERT(observer != NULL); |
355 if (!observer) | 363 if (!observer) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 port_allocator_->set_step_delay(cricket::kMinimumStepDelay); | 399 port_allocator_->set_step_delay(cricket::kMinimumStepDelay); |
392 | 400 |
393 mediastream_signaling_.reset(new MediaStreamSignaling( | 401 mediastream_signaling_.reset(new MediaStreamSignaling( |
394 factory_->signaling_thread(), this, factory_->channel_manager())); | 402 factory_->signaling_thread(), this, factory_->channel_manager())); |
395 | 403 |
396 session_.reset(new WebRtcSession(factory_->channel_manager(), | 404 session_.reset(new WebRtcSession(factory_->channel_manager(), |
397 factory_->signaling_thread(), | 405 factory_->signaling_thread(), |
398 factory_->worker_thread(), | 406 factory_->worker_thread(), |
399 port_allocator_.get(), | 407 port_allocator_.get(), |
400 mediastream_signaling_.get())); | 408 mediastream_signaling_.get())); |
401 stream_handler_container_.reset(new MediaStreamHandlerContainer( | |
402 session_.get(), session_.get())); | |
403 stats_.reset(new StatsCollector(session_.get())); | 409 stats_.reset(new StatsCollector(session_.get())); |
404 | 410 |
405 // Initialize the WebRtcSession. It creates transport channels etc. | 411 // Initialize the WebRtcSession. It creates transport channels etc. |
406 if (!session_->Initialize(factory_->options(), constraints, | 412 if (!session_->Initialize(factory_->options(), constraints, |
407 dtls_identity_store.Pass(), configuration)) | 413 dtls_identity_store.Pass(), configuration)) |
408 return false; | 414 return false; |
409 | 415 |
410 // Register PeerConnection as receiver of local ice candidates. | 416 // Register PeerConnection as receiver of local ice candidates. |
411 // All the callbacks will be posted to the application from PeerConnection. | 417 // All the callbacks will be posted to the application from PeerConnection. |
412 session_->RegisterIceObserver(this); | 418 session_->RegisterIceObserver(this); |
413 session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange); | 419 session_->SignalState.connect(this, &PeerConnection::OnSessionStateChange); |
414 return true; | 420 return true; |
415 } | 421 } |
416 | 422 |
417 rtc::scoped_refptr<StreamCollectionInterface> | 423 rtc::scoped_refptr<StreamCollectionInterface> |
418 PeerConnection::local_streams() { | 424 PeerConnection::local_streams() { |
419 return mediastream_signaling_->local_streams(); | 425 return mediastream_signaling_->local_streams(); |
420 } | 426 } |
421 | 427 |
422 rtc::scoped_refptr<StreamCollectionInterface> | 428 rtc::scoped_refptr<StreamCollectionInterface> |
423 PeerConnection::remote_streams() { | 429 PeerConnection::remote_streams() { |
424 return mediastream_signaling_->remote_streams(); | 430 return mediastream_signaling_->remote_streams(); |
425 } | 431 } |
426 | 432 |
| 433 // TODO(deadbeef): Create RtpSenders immediately here, even if local |
| 434 // description hasn't yet been set. |
427 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { | 435 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { |
428 if (IsClosed()) { | 436 if (IsClosed()) { |
429 return false; | 437 return false; |
430 } | 438 } |
431 if (!CanAddLocalMediaStream(mediastream_signaling_->local_streams(), | 439 if (!CanAddLocalMediaStream(mediastream_signaling_->local_streams(), |
432 local_stream)) | 440 local_stream)) |
433 return false; | 441 return false; |
434 | 442 |
435 if (!mediastream_signaling_->AddLocalStream(local_stream)) { | 443 if (!mediastream_signaling_->AddLocalStream(local_stream)) { |
436 return false; | 444 return false; |
(...skipping 24 matching lines...) Expand all Loading... |
461 | 469 |
462 rtc::scoped_refptr<DtmfSenderInterface> sender( | 470 rtc::scoped_refptr<DtmfSenderInterface> sender( |
463 DtmfSender::Create(track, signaling_thread(), session_.get())); | 471 DtmfSender::Create(track, signaling_thread(), session_.get())); |
464 if (!sender.get()) { | 472 if (!sender.get()) { |
465 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; | 473 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; |
466 return NULL; | 474 return NULL; |
467 } | 475 } |
468 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); | 476 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); |
469 } | 477 } |
470 | 478 |
| 479 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders() |
| 480 const { |
| 481 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders; |
| 482 for (const auto& sender : senders_) { |
| 483 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get())); |
| 484 } |
| 485 return senders; |
| 486 } |
| 487 |
| 488 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> |
| 489 PeerConnection::GetReceivers() const { |
| 490 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers; |
| 491 for (const auto& receiver : receivers_) { |
| 492 receivers.push_back( |
| 493 RtpReceiverProxy::Create(signaling_thread(), receiver.get())); |
| 494 } |
| 495 return receivers; |
| 496 } |
| 497 |
471 bool PeerConnection::GetStats(StatsObserver* observer, | 498 bool PeerConnection::GetStats(StatsObserver* observer, |
472 MediaStreamTrackInterface* track, | 499 MediaStreamTrackInterface* track, |
473 StatsOutputLevel level) { | 500 StatsOutputLevel level) { |
474 ASSERT(signaling_thread()->IsCurrent()); | 501 ASSERT(signaling_thread()->IsCurrent()); |
475 if (!VERIFY(observer != NULL)) { | 502 if (!VERIFY(observer != NULL)) { |
476 LOG(LS_ERROR) << "GetStats - observer is NULL."; | 503 LOG(LS_ERROR) << "GetStats - observer is NULL."; |
477 return false; | 504 return false; |
478 } | 505 } |
479 | 506 |
480 stats_->UpdateStats(level); | 507 stats_->UpdateStats(level); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 break; | 828 break; |
802 } | 829 } |
803 } | 830 } |
804 | 831 |
805 void PeerConnection::OnAddRemoteStream(MediaStreamInterface* stream) { | 832 void PeerConnection::OnAddRemoteStream(MediaStreamInterface* stream) { |
806 stats_->AddStream(stream); | 833 stats_->AddStream(stream); |
807 observer_->OnAddStream(stream); | 834 observer_->OnAddStream(stream); |
808 } | 835 } |
809 | 836 |
810 void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) { | 837 void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) { |
811 stream_handler_container_->RemoveRemoteStream(stream); | |
812 observer_->OnRemoveStream(stream); | 838 observer_->OnRemoveStream(stream); |
813 } | 839 } |
814 | 840 |
815 void PeerConnection::OnAddDataChannel(DataChannelInterface* data_channel) { | 841 void PeerConnection::OnAddDataChannel(DataChannelInterface* data_channel) { |
816 observer_->OnDataChannel(DataChannelProxy::Create(signaling_thread(), | 842 observer_->OnDataChannel(DataChannelProxy::Create(signaling_thread(), |
817 data_channel)); | 843 data_channel)); |
818 } | 844 } |
819 | 845 |
820 void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream, | 846 void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream, |
821 AudioTrackInterface* audio_track, | 847 AudioTrackInterface* audio_track, |
822 uint32 ssrc) { | 848 uint32 ssrc) { |
823 stream_handler_container_->AddRemoteAudioTrack(stream, audio_track, ssrc); | 849 receivers_.push_back(new AudioRtpReceiver(audio_track, ssrc, session_.get())); |
824 } | 850 } |
825 | 851 |
826 void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream, | 852 void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream, |
827 VideoTrackInterface* video_track, | 853 VideoTrackInterface* video_track, |
828 uint32 ssrc) { | 854 uint32 ssrc) { |
829 stream_handler_container_->AddRemoteVideoTrack(stream, video_track, ssrc); | 855 receivers_.push_back(new VideoRtpReceiver(video_track, ssrc, session_.get())); |
830 } | 856 } |
831 | 857 |
| 858 // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote |
| 859 // description. |
832 void PeerConnection::OnRemoveRemoteAudioTrack( | 860 void PeerConnection::OnRemoveRemoteAudioTrack( |
833 MediaStreamInterface* stream, | 861 MediaStreamInterface* stream, |
834 AudioTrackInterface* audio_track) { | 862 AudioTrackInterface* audio_track) { |
835 stream_handler_container_->RemoveRemoteTrack(stream, audio_track); | 863 auto it = FindReceiverForTrack(audio_track); |
| 864 if (it == receivers_.end()) { |
| 865 LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id() |
| 866 << " doesn't exist."; |
| 867 } else { |
| 868 (*it)->Stop(); |
| 869 receivers_.erase(it); |
| 870 } |
836 } | 871 } |
837 | 872 |
838 void PeerConnection::OnRemoveRemoteVideoTrack( | 873 void PeerConnection::OnRemoveRemoteVideoTrack( |
839 MediaStreamInterface* stream, | 874 MediaStreamInterface* stream, |
840 VideoTrackInterface* video_track) { | 875 VideoTrackInterface* video_track) { |
841 stream_handler_container_->RemoveRemoteTrack(stream, video_track); | 876 auto it = FindReceiverForTrack(video_track); |
| 877 if (it == receivers_.end()) { |
| 878 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() |
| 879 << " doesn't exist."; |
| 880 } else { |
| 881 (*it)->Stop(); |
| 882 receivers_.erase(it); |
| 883 } |
842 } | 884 } |
| 885 |
843 void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream, | 886 void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream, |
844 AudioTrackInterface* audio_track, | 887 AudioTrackInterface* audio_track, |
845 uint32 ssrc) { | 888 uint32 ssrc) { |
846 stream_handler_container_->AddLocalAudioTrack(stream, audio_track, ssrc); | 889 senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get())); |
847 stats_->AddLocalAudioTrack(audio_track, ssrc); | 890 stats_->AddLocalAudioTrack(audio_track, ssrc); |
848 } | 891 } |
| 892 |
849 void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream, | 893 void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream, |
850 VideoTrackInterface* video_track, | 894 VideoTrackInterface* video_track, |
851 uint32 ssrc) { | 895 uint32 ssrc) { |
852 stream_handler_container_->AddLocalVideoTrack(stream, video_track, ssrc); | 896 senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get())); |
853 } | 897 } |
854 | 898 |
| 899 // TODO(deadbeef): Keep RtpSenders around even if track goes away in local |
| 900 // description. |
855 void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream, | 901 void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream, |
856 AudioTrackInterface* audio_track, | 902 AudioTrackInterface* audio_track, |
857 uint32 ssrc) { | 903 uint32 ssrc) { |
858 stream_handler_container_->RemoveLocalTrack(stream, audio_track); | 904 auto it = FindSenderForTrack(audio_track); |
| 905 if (it == senders_.end()) { |
| 906 LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id() |
| 907 << " doesn't exist."; |
| 908 return; |
| 909 } else { |
| 910 (*it)->Stop(); |
| 911 senders_.erase(it); |
| 912 } |
859 stats_->RemoveLocalAudioTrack(audio_track, ssrc); | 913 stats_->RemoveLocalAudioTrack(audio_track, ssrc); |
860 } | 914 } |
861 | 915 |
862 void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream, | 916 void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream, |
863 VideoTrackInterface* video_track) { | 917 VideoTrackInterface* video_track) { |
864 stream_handler_container_->RemoveLocalTrack(stream, video_track); | 918 auto it = FindSenderForTrack(video_track); |
| 919 if (it == senders_.end()) { |
| 920 LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id() |
| 921 << " doesn't exist."; |
| 922 return; |
| 923 } else { |
| 924 (*it)->Stop(); |
| 925 senders_.erase(it); |
| 926 } |
865 } | 927 } |
866 | 928 |
867 void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) { | 929 void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) { |
868 stream_handler_container_->RemoveLocalStream(stream); | |
869 } | 930 } |
870 | 931 |
871 void PeerConnection::OnIceConnectionChange( | 932 void PeerConnection::OnIceConnectionChange( |
872 PeerConnectionInterface::IceConnectionState new_state) { | 933 PeerConnectionInterface::IceConnectionState new_state) { |
873 ASSERT(signaling_thread()->IsCurrent()); | 934 ASSERT(signaling_thread()->IsCurrent()); |
874 // After transitioning to "closed", ignore any additional states from | 935 // After transitioning to "closed", ignore any additional states from |
875 // WebRtcSession (such as "disconnected"). | 936 // WebRtcSession (such as "disconnected"). |
876 if (ice_connection_state_ == kIceConnectionClosed) { | 937 if (ice_connection_state_ == kIceConnectionClosed) { |
877 return; | 938 return; |
878 } | 939 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 observer_->OnIceConnectionChange(ice_connection_state_); | 974 observer_->OnIceConnectionChange(ice_connection_state_); |
914 if (ice_gathering_state_ != kIceGatheringComplete) { | 975 if (ice_gathering_state_ != kIceGatheringComplete) { |
915 ice_gathering_state_ = kIceGatheringComplete; | 976 ice_gathering_state_ = kIceGatheringComplete; |
916 observer_->OnIceGatheringChange(ice_gathering_state_); | 977 observer_->OnIceGatheringChange(ice_gathering_state_); |
917 } | 978 } |
918 } | 979 } |
919 observer_->OnSignalingChange(signaling_state_); | 980 observer_->OnSignalingChange(signaling_state_); |
920 observer_->OnStateChange(PeerConnectionObserver::kSignalingState); | 981 observer_->OnStateChange(PeerConnectionObserver::kSignalingState); |
921 } | 982 } |
922 | 983 |
| 984 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator |
| 985 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) { |
| 986 return std::find_if( |
| 987 senders_.begin(), senders_.end(), |
| 988 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) { |
| 989 return sender->track() == track; |
| 990 }); |
| 991 } |
| 992 |
| 993 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator |
| 994 PeerConnection::FindReceiverForTrack(MediaStreamTrackInterface* track) { |
| 995 return std::find_if( |
| 996 receivers_.begin(), receivers_.end(), |
| 997 [track](const rtc::scoped_refptr<RtpReceiverInterface>& receiver) { |
| 998 return receiver->track() == track; |
| 999 }); |
| 1000 } |
| 1001 |
923 } // namespace webrtc | 1002 } // namespace webrtc |
OLD | NEW |