Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: talk/app/webrtc/peerconnection.cc

Issue 1507973003: Restoring behavior where PeerConnection tracks changes to MediaStreams. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing merge conflicts. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « talk/app/webrtc/peerconnection.h ('k') | talk/app/webrtc/peerconnectioninterface_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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,
11 * this list of conditions and the following disclaimer in the documentation 11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution. 12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products 13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 #include "talk/app/webrtc/peerconnection.h" 28 #include "talk/app/webrtc/peerconnection.h"
29 29
30 #include <algorithm>
30 #include <vector> 31 #include <vector>
31 #include <cctype> // for isdigit 32 #include <cctype> // for isdigit
32 33
33 #include "talk/app/webrtc/audiotrack.h" 34 #include "talk/app/webrtc/audiotrack.h"
34 #include "talk/app/webrtc/dtmfsender.h" 35 #include "talk/app/webrtc/dtmfsender.h"
35 #include "talk/app/webrtc/jsepicecandidate.h" 36 #include "talk/app/webrtc/jsepicecandidate.h"
36 #include "talk/app/webrtc/jsepsessiondescription.h" 37 #include "talk/app/webrtc/jsepsessiondescription.h"
37 #include "talk/app/webrtc/mediaconstraintsinterface.h" 38 #include "talk/app/webrtc/mediaconstraintsinterface.h"
38 #include "talk/app/webrtc/mediastream.h" 39 #include "talk/app/webrtc/mediastream.h"
40 #include "talk/app/webrtc/mediastreamobserver.h"
39 #include "talk/app/webrtc/mediastreamproxy.h" 41 #include "talk/app/webrtc/mediastreamproxy.h"
40 #include "talk/app/webrtc/mediastreamtrackproxy.h" 42 #include "talk/app/webrtc/mediastreamtrackproxy.h"
41 #include "talk/app/webrtc/remoteaudiosource.h" 43 #include "talk/app/webrtc/remoteaudiosource.h"
42 #include "talk/app/webrtc/remoteaudiotrack.h" 44 #include "talk/app/webrtc/remoteaudiotrack.h"
43 #include "talk/app/webrtc/remotevideocapturer.h" 45 #include "talk/app/webrtc/remotevideocapturer.h"
44 #include "talk/app/webrtc/rtpreceiver.h" 46 #include "talk/app/webrtc/rtpreceiver.h"
45 #include "talk/app/webrtc/rtpsender.h" 47 #include "talk/app/webrtc/rtpsender.h"
46 #include "talk/app/webrtc/streamcollection.h" 48 #include "talk/app/webrtc/streamcollection.h"
47 #include "talk/app/webrtc/videosource.h" 49 #include "talk/app/webrtc/videosource.h"
48 #include "talk/app/webrtc/videotrack.h" 50 #include "talk/app/webrtc/videotrack.h"
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { 735 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
734 TRACE_EVENT0("webrtc", "PeerConnection::AddStream"); 736 TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
735 if (IsClosed()) { 737 if (IsClosed()) {
736 return false; 738 return false;
737 } 739 }
738 if (!CanAddLocalMediaStream(local_streams_, local_stream)) { 740 if (!CanAddLocalMediaStream(local_streams_, local_stream)) {
739 return false; 741 return false;
740 } 742 }
741 743
742 local_streams_->AddStream(local_stream); 744 local_streams_->AddStream(local_stream);
745 MediaStreamObserver* observer = new MediaStreamObserver(local_stream);
746 observer->SignalAudioTrackAdded.connect(this,
747 &PeerConnection::OnAudioTrackAdded);
748 observer->SignalAudioTrackRemoved.connect(
749 this, &PeerConnection::OnAudioTrackRemoved);
750 observer->SignalVideoTrackAdded.connect(this,
751 &PeerConnection::OnVideoTrackAdded);
752 observer->SignalVideoTrackRemoved.connect(
753 this, &PeerConnection::OnVideoTrackRemoved);
754 stream_observers_.push_back(rtc::scoped_ptr<MediaStreamObserver>(observer));
743 755
744 for (const auto& track : local_stream->GetAudioTracks()) { 756 for (const auto& track : local_stream->GetAudioTracks()) {
745 auto sender = FindSenderForTrack(track.get()); 757 OnAudioTrackAdded(track.get(), local_stream);
746 if (sender == senders_.end()) {
747 // Normal case; we've never seen this track before.
748 AudioRtpSender* new_sender = new AudioRtpSender(
749 track.get(), local_stream->label(), session_.get(), stats_.get());
750 senders_.push_back(new_sender);
751 // If the sender has already been configured in SDP, we call SetSsrc,
752 // which will connect the sender to the underlying transport. This can
753 // occur if a local session description that contains the ID of the sender
754 // is set before AddStream is called. It can also occur if the local
755 // session description is not changed and RemoveStream is called, and
756 // later AddStream is called again with the same stream.
757 const TrackInfo* track_info = FindTrackInfo(
758 local_audio_tracks_, local_stream->label(), track->id());
759 if (track_info) {
760 new_sender->SetSsrc(track_info->ssrc);
761 }
762 } else {
763 // We already have a sender for this track, so just change the stream_id
764 // so that it's correct in the next call to CreateOffer.
765 (*sender)->set_stream_id(local_stream->label());
766 }
767 } 758 }
768 for (const auto& track : local_stream->GetVideoTracks()) { 759 for (const auto& track : local_stream->GetVideoTracks()) {
769 auto sender = FindSenderForTrack(track.get()); 760 OnVideoTrackAdded(track.get(), local_stream);
770 if (sender == senders_.end()) {
771 // Normal case; we've never seen this track before.
772 VideoRtpSender* new_sender = new VideoRtpSender(
773 track.get(), local_stream->label(), session_.get());
774 senders_.push_back(new_sender);
775 const TrackInfo* track_info = FindTrackInfo(
776 local_video_tracks_, local_stream->label(), track->id());
777 if (track_info) {
778 new_sender->SetSsrc(track_info->ssrc);
779 }
780 } else {
781 // We already have a sender for this track, so just change the stream_id
782 // so that it's correct in the next call to CreateOffer.
783 (*sender)->set_stream_id(local_stream->label());
784 }
785 } 761 }
786 762
787 stats_->AddStream(local_stream); 763 stats_->AddStream(local_stream);
788 observer_->OnRenegotiationNeeded(); 764 observer_->OnRenegotiationNeeded();
789 return true; 765 return true;
790 } 766 }
791 767
792 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around
793 // indefinitely, when we have unified plan SDP.
794 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { 768 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
795 TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream"); 769 TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
796 for (const auto& track : local_stream->GetAudioTracks()) { 770 for (const auto& track : local_stream->GetAudioTracks()) {
797 auto sender = FindSenderForTrack(track.get()); 771 OnAudioTrackRemoved(track.get(), local_stream);
798 if (sender == senders_.end()) {
799 LOG(LS_WARNING) << "RtpSender for track with id " << track->id()
800 << " doesn't exist.";
801 continue;
802 }
803 (*sender)->Stop();
804 senders_.erase(sender);
805 } 772 }
806 for (const auto& track : local_stream->GetVideoTracks()) { 773 for (const auto& track : local_stream->GetVideoTracks()) {
807 auto sender = FindSenderForTrack(track.get()); 774 OnVideoTrackRemoved(track.get(), local_stream);
808 if (sender == senders_.end()) {
809 LOG(LS_WARNING) << "RtpSender for track with id " << track->id()
810 << " doesn't exist.";
811 continue;
812 }
813 (*sender)->Stop();
814 senders_.erase(sender);
815 } 775 }
816 776
817 local_streams_->RemoveStream(local_stream); 777 local_streams_->RemoveStream(local_stream);
778 stream_observers_.erase(
779 std::remove_if(
780 stream_observers_.begin(), stream_observers_.end(),
781 [local_stream](const rtc::scoped_ptr<MediaStreamObserver>& observer) {
782 return observer->stream()->label().compare(local_stream->label()) ==
783 0;
784 }),
785 stream_observers_.end());
818 786
819 if (IsClosed()) { 787 if (IsClosed()) {
820 return; 788 return;
821 } 789 }
822 observer_->OnRenegotiationNeeded(); 790 observer_->OnRenegotiationNeeded();
823 } 791 }
824 792
825 rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender( 793 rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender(
826 AudioTrackInterface* track) { 794 AudioTrackInterface* track) {
827 TRACE_EVENT0("webrtc", "PeerConnection::CreateDtmfSender"); 795 TRACE_EVENT0("webrtc", "PeerConnection::CreateDtmfSender");
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 observer_->OnIceConnectionChange(ice_connection_state_); 1389 observer_->OnIceConnectionChange(ice_connection_state_);
1422 if (ice_gathering_state_ != kIceGatheringComplete) { 1390 if (ice_gathering_state_ != kIceGatheringComplete) {
1423 ice_gathering_state_ = kIceGatheringComplete; 1391 ice_gathering_state_ = kIceGatheringComplete;
1424 observer_->OnIceGatheringChange(ice_gathering_state_); 1392 observer_->OnIceGatheringChange(ice_gathering_state_);
1425 } 1393 }
1426 } 1394 }
1427 observer_->OnSignalingChange(signaling_state_); 1395 observer_->OnSignalingChange(signaling_state_);
1428 observer_->OnStateChange(PeerConnectionObserver::kSignalingState); 1396 observer_->OnStateChange(PeerConnectionObserver::kSignalingState);
1429 } 1397 }
1430 1398
1399 void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track,
1400 MediaStreamInterface* stream) {
1401 auto sender = FindSenderForTrack(track);
1402 if (sender != senders_.end()) {
1403 // We already have a sender for this track, so just change the stream_id
1404 // so that it's correct in the next call to CreateOffer.
1405 (*sender)->set_stream_id(stream->label());
1406 return;
1407 }
1408
1409 // Normal case; we've never seen this track before.
1410 AudioRtpSender* new_sender =
1411 new AudioRtpSender(track, stream->label(), session_.get(), stats_.get());
1412 senders_.push_back(new_sender);
1413 // If the sender has already been configured in SDP, we call SetSsrc,
1414 // which will connect the sender to the underlying transport. This can
1415 // occur if a local session description that contains the ID of the sender
1416 // is set before AddStream is called. It can also occur if the local
1417 // session description is not changed and RemoveStream is called, and
1418 // later AddStream is called again with the same stream.
1419 const TrackInfo* track_info =
1420 FindTrackInfo(local_audio_tracks_, stream->label(), track->id());
1421 if (track_info) {
1422 new_sender->SetSsrc(track_info->ssrc);
1423 }
1424 }
1425
1426 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around
1427 // indefinitely, when we have unified plan SDP.
1428 void PeerConnection::OnAudioTrackRemoved(AudioTrackInterface* track,
1429 MediaStreamInterface* stream) {
1430 auto sender = FindSenderForTrack(track);
1431 if (sender == senders_.end()) {
1432 LOG(LS_WARNING) << "RtpSender for track with id " << track->id()
1433 << " doesn't exist.";
1434 return;
1435 }
1436 (*sender)->Stop();
1437 senders_.erase(sender);
1438 }
1439
1440 void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track,
1441 MediaStreamInterface* stream) {
1442 auto sender = FindSenderForTrack(track);
1443 if (sender != senders_.end()) {
1444 // We already have a sender for this track, so just change the stream_id
1445 // so that it's correct in the next call to CreateOffer.
1446 (*sender)->set_stream_id(stream->label());
1447 return;
1448 }
1449
1450 // Normal case; we've never seen this track before.
1451 VideoRtpSender* new_sender =
1452 new VideoRtpSender(track, stream->label(), session_.get());
1453 senders_.push_back(new_sender);
1454 const TrackInfo* track_info =
1455 FindTrackInfo(local_video_tracks_, stream->label(), track->id());
1456 if (track_info) {
1457 new_sender->SetSsrc(track_info->ssrc);
1458 }
1459 }
1460
1461 void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track,
1462 MediaStreamInterface* stream) {
1463 auto sender = FindSenderForTrack(track);
1464 if (sender == senders_.end()) {
1465 LOG(LS_WARNING) << "RtpSender for track with id " << track->id()
1466 << " doesn't exist.";
1467 return;
1468 }
1469 (*sender)->Stop();
1470 senders_.erase(sender);
1471 }
1472
1431 void PeerConnection::PostSetSessionDescriptionFailure( 1473 void PeerConnection::PostSetSessionDescriptionFailure(
1432 SetSessionDescriptionObserver* observer, 1474 SetSessionDescriptionObserver* observer,
1433 const std::string& error) { 1475 const std::string& error) {
1434 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); 1476 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
1435 msg->error = error; 1477 msg->error = error;
1436 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_FAILED, msg); 1478 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_FAILED, msg);
1437 } 1479 }
1438 1480
1439 void PeerConnection::PostCreateSessionDescriptionFailure( 1481 void PeerConnection::PostCreateSessionDescriptionFailure(
1440 CreateSessionDescriptionObserver* observer, 1482 CreateSessionDescriptionObserver* observer,
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
2020 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { 2062 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const {
2021 for (const auto& channel : sctp_data_channels_) { 2063 for (const auto& channel : sctp_data_channels_) {
2022 if (channel->id() == sid) { 2064 if (channel->id() == sid) {
2023 return channel; 2065 return channel;
2024 } 2066 }
2025 } 2067 }
2026 return nullptr; 2068 return nullptr;
2027 } 2069 }
2028 2070
2029 } // namespace webrtc 2071 } // namespace webrtc
OLDNEW
« no previous file with comments | « talk/app/webrtc/peerconnection.h ('k') | talk/app/webrtc/peerconnectioninterface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698