Chromium Code Reviews| 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& pair : rtp_sender_pairs_) { | |
| 347 pair.first->DetachFromProvider(); | |
| 348 } | |
| 349 for (const auto& pair : rtp_receiver_pairs_) { | |
| 350 pair.first->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. | |
|
pthatcher1
2015/09/23 14:47:39
More like "Replace with addTrack, which may create
pthatcher1
2015/09/24 06:32:29
Can you update this comment?
| |
| 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& pair : rtp_sender_pairs_) { | |
| 481 senders.push_back(pair.second); | |
| 482 } | |
| 483 return senders; | |
| 484 } | |
| 485 | |
| 486 RtpReceiverRefptrs PeerConnection::GetReceivers() const { | |
| 487 RtpReceiverRefptrs receivers; | |
| 488 for (const auto& pair : rtp_receiver_pairs_) { | |
| 489 receivers.push_back(pair.second); | |
| 490 } | |
| 491 return receivers; | |
| 492 } | |
| 493 | |
| 472 bool PeerConnection::GetStats(StatsObserver* observer, | 494 bool PeerConnection::GetStats(StatsObserver* observer, |
| 473 MediaStreamTrackInterface* track, | 495 MediaStreamTrackInterface* track, |
| 474 StatsOutputLevel level) { | 496 StatsOutputLevel level) { |
| 475 ASSERT(signaling_thread()->IsCurrent()); | 497 ASSERT(signaling_thread()->IsCurrent()); |
| 476 if (!VERIFY(observer != NULL)) { | 498 if (!VERIFY(observer != NULL)) { |
| 477 LOG(LS_ERROR) << "GetStats - observer is NULL."; | 499 LOG(LS_ERROR) << "GetStats - observer is NULL."; |
| 478 return false; | 500 return false; |
| 479 } | 501 } |
| 480 | 502 |
| 481 stats_->UpdateStats(level); | 503 stats_->UpdateStats(level); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 799 break; | 821 break; |
| 800 } | 822 } |
| 801 } | 823 } |
| 802 | 824 |
| 803 void PeerConnection::OnAddRemoteStream(MediaStreamInterface* stream) { | 825 void PeerConnection::OnAddRemoteStream(MediaStreamInterface* stream) { |
| 804 stats_->AddStream(stream); | 826 stats_->AddStream(stream); |
| 805 observer_->OnAddStream(stream); | 827 observer_->OnAddStream(stream); |
| 806 } | 828 } |
| 807 | 829 |
| 808 void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) { | 830 void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) { |
| 809 stream_handler_container_->RemoveRemoteStream(stream); | |
| 810 observer_->OnRemoveStream(stream); | 831 observer_->OnRemoveStream(stream); |
| 811 } | 832 } |
| 812 | 833 |
| 813 void PeerConnection::OnAddDataChannel(DataChannelInterface* data_channel) { | 834 void PeerConnection::OnAddDataChannel(DataChannelInterface* data_channel) { |
| 814 observer_->OnDataChannel(DataChannelProxy::Create(signaling_thread(), | 835 observer_->OnDataChannel(DataChannelProxy::Create(signaling_thread(), |
| 815 data_channel)); | 836 data_channel)); |
| 816 } | 837 } |
| 817 | 838 |
| 818 void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream, | 839 void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream, |
| 819 AudioTrackInterface* audio_track, | 840 AudioTrackInterface* audio_track, |
| 820 uint32 ssrc) { | 841 uint32 ssrc) { |
| 821 stream_handler_container_->AddRemoteAudioTrack(stream, audio_track, ssrc); | 842 AddRtpReceiver(new AudioRtpReceiver(audio_track, ssrc, session_.get())); |
| 822 } | 843 } |
| 823 | 844 |
| 824 void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream, | 845 void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream, |
| 825 VideoTrackInterface* video_track, | 846 VideoTrackInterface* video_track, |
| 826 uint32 ssrc) { | 847 uint32 ssrc) { |
| 827 stream_handler_container_->AddRemoteVideoTrack(stream, video_track, ssrc); | 848 AddRtpReceiver(new VideoRtpReceiver(video_track, ssrc, session_.get())); |
| 828 } | 849 } |
| 829 | 850 |
| 851 // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote | |
| 852 // description. | |
|
pthatcher1
2015/09/23 14:47:39
Well, in unified plan m-lines can never go away.
| |
| 830 void PeerConnection::OnRemoveRemoteAudioTrack( | 853 void PeerConnection::OnRemoveRemoteAudioTrack( |
| 831 MediaStreamInterface* stream, | 854 MediaStreamInterface* stream, |
| 832 AudioTrackInterface* audio_track) { | 855 AudioTrackInterface* audio_track) { |
| 833 stream_handler_container_->RemoveRemoteTrack(stream, audio_track); | 856 auto it = FindRtpReceiverPairForTrack(audio_track); |
| 857 if (it == rtp_receiver_pairs_.end()) { | |
| 858 LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id() | |
| 859 << " doesn't exist."; | |
| 860 } else { | |
| 861 it->first->DetachFromProvider(); | |
| 862 rtp_receiver_pairs_.erase(it); | |
| 863 } | |
| 834 } | 864 } |
| 835 | 865 |
| 836 void PeerConnection::OnRemoveRemoteVideoTrack( | 866 void PeerConnection::OnRemoveRemoteVideoTrack( |
| 837 MediaStreamInterface* stream, | 867 MediaStreamInterface* stream, |
| 838 VideoTrackInterface* video_track) { | 868 VideoTrackInterface* video_track) { |
| 839 stream_handler_container_->RemoveRemoteTrack(stream, video_track); | 869 auto it = FindRtpReceiverPairForTrack(video_track); |
| 870 if (it == rtp_receiver_pairs_.end()) { | |
| 871 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() | |
| 872 << " doesn't exist."; | |
| 873 } else { | |
| 874 it->first->DetachFromProvider(); | |
| 875 rtp_receiver_pairs_.erase(it); | |
| 876 } | |
| 840 } | 877 } |
| 878 | |
| 841 void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream, | 879 void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream, |
| 842 AudioTrackInterface* audio_track, | 880 AudioTrackInterface* audio_track, |
| 843 uint32 ssrc) { | 881 uint32 ssrc) { |
| 844 stream_handler_container_->AddLocalAudioTrack(stream, audio_track, ssrc); | 882 AddRtpSender(new AudioRtpSender(audio_track, ssrc, session_.get())); |
| 845 stats_->AddLocalAudioTrack(audio_track, ssrc); | 883 stats_->AddLocalAudioTrack(audio_track, ssrc); |
| 846 } | 884 } |
| 885 | |
| 847 void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream, | 886 void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream, |
| 848 VideoTrackInterface* video_track, | 887 VideoTrackInterface* video_track, |
| 849 uint32 ssrc) { | 888 uint32 ssrc) { |
| 850 stream_handler_container_->AddLocalVideoTrack(stream, video_track, ssrc); | 889 AddRtpSender(new VideoRtpSender(video_track, ssrc, session_.get())); |
| 851 } | 890 } |
| 852 | 891 |
| 892 // TODO(deadbeef): Keep RtpSenders around even if track goes away in local | |
| 893 // description. | |
| 853 void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream, | 894 void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream, |
| 854 AudioTrackInterface* audio_track, | 895 AudioTrackInterface* audio_track, |
| 855 uint32 ssrc) { | 896 uint32 ssrc) { |
| 856 stream_handler_container_->RemoveLocalTrack(stream, audio_track); | 897 auto it = FindRtpSenderPairForTrack(audio_track); |
| 898 if (it == rtp_sender_pairs_.end()) { | |
| 899 LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id() | |
| 900 << " doesn't exist."; | |
| 901 return; | |
| 902 } else { | |
| 903 it->first->DetachFromProvider(); | |
| 904 rtp_sender_pairs_.erase(it); | |
| 905 } | |
| 857 stats_->RemoveLocalAudioTrack(audio_track, ssrc); | 906 stats_->RemoveLocalAudioTrack(audio_track, ssrc); |
| 858 } | 907 } |
| 859 | 908 |
| 860 void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream, | 909 void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream, |
| 861 VideoTrackInterface* video_track) { | 910 VideoTrackInterface* video_track) { |
| 862 stream_handler_container_->RemoveLocalTrack(stream, video_track); | 911 auto it = FindRtpSenderPairForTrack(video_track); |
| 912 if (it == rtp_sender_pairs_.end()) { | |
| 913 LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id() | |
| 914 << " doesn't exist."; | |
| 915 return; | |
| 916 } else { | |
| 917 it->first->DetachFromProvider(); | |
| 918 rtp_sender_pairs_.erase(it); | |
| 919 } | |
| 863 } | 920 } |
| 864 | 921 |
| 865 void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) { | 922 void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) { |
| 866 stream_handler_container_->RemoveLocalStream(stream); | |
| 867 } | 923 } |
| 868 | 924 |
| 869 void PeerConnection::OnIceConnectionChange( | 925 void PeerConnection::OnIceConnectionChange( |
| 870 PeerConnectionInterface::IceConnectionState new_state) { | 926 PeerConnectionInterface::IceConnectionState new_state) { |
| 871 ASSERT(signaling_thread()->IsCurrent()); | 927 ASSERT(signaling_thread()->IsCurrent()); |
| 872 ice_connection_state_ = new_state; | 928 ice_connection_state_ = new_state; |
| 873 observer_->OnIceConnectionChange(ice_connection_state_); | 929 observer_->OnIceConnectionChange(ice_connection_state_); |
| 874 } | 930 } |
| 875 | 931 |
| 876 void PeerConnection::OnIceGatheringChange( | 932 void PeerConnection::OnIceGatheringChange( |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 906 observer_->OnIceConnectionChange(ice_connection_state_); | 962 observer_->OnIceConnectionChange(ice_connection_state_); |
| 907 if (ice_gathering_state_ != kIceGatheringComplete) { | 963 if (ice_gathering_state_ != kIceGatheringComplete) { |
| 908 ice_gathering_state_ = kIceGatheringComplete; | 964 ice_gathering_state_ = kIceGatheringComplete; |
| 909 observer_->OnIceGatheringChange(ice_gathering_state_); | 965 observer_->OnIceGatheringChange(ice_gathering_state_); |
| 910 } | 966 } |
| 911 } | 967 } |
| 912 observer_->OnSignalingChange(signaling_state_); | 968 observer_->OnSignalingChange(signaling_state_); |
| 913 observer_->OnStateChange(PeerConnectionObserver::kSignalingState); | 969 observer_->OnStateChange(PeerConnectionObserver::kSignalingState); |
| 914 } | 970 } |
| 915 | 971 |
| 972 void PeerConnection::AddRtpSender(BaseRtpSender* sender) { | |
| 973 rtp_sender_pairs_.push_back(RtpSenderPair( | |
| 974 sender, RtpSenderProxy::Create(signaling_thread(), sender))); | |
| 975 } | |
| 976 | |
| 977 void PeerConnection::AddRtpReceiver(BaseRtpReceiver* receiver) { | |
| 978 rtp_receiver_pairs_.push_back(RtpReceiverPair( | |
| 979 receiver, RtpReceiverProxy::Create(signaling_thread(), receiver))); | |
| 980 } | |
| 981 | |
| 982 PeerConnection::RtpSenderPairList::iterator | |
| 983 PeerConnection::FindRtpSenderPairForTrack(MediaStreamTrackInterface* track) { | |
| 984 return std::find_if(rtp_sender_pairs_.begin(), rtp_sender_pairs_.end(), | |
| 985 [track](const RtpSenderPair& pair) { | |
| 986 return pair.first->track() == track; | |
| 987 }); | |
| 988 } | |
| 989 | |
| 990 PeerConnection::RtpReceiverPairList::iterator | |
| 991 PeerConnection::FindRtpReceiverPairForTrack(MediaStreamTrackInterface* track) { | |
| 992 return std::find_if(rtp_receiver_pairs_.begin(), rtp_receiver_pairs_.end(), | |
| 993 [track](const RtpReceiverPair& pair) { | |
| 994 return pair.first->track() == track; | |
| 995 }); | |
| 996 } | |
| 997 | |
| 916 } // namespace webrtc | 998 } // namespace webrtc |
| OLD | NEW |