Index: talk/app/webrtc/peerconnection.cc |
diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc |
index f0db1397aa7941612612ea3be8cb010b0b09c854..a24dd7edbe2c87c3bcf3cc4644a845959b776fc4 100644 |
--- a/talk/app/webrtc/peerconnection.cc |
+++ b/talk/app/webrtc/peerconnection.cc |
@@ -27,6 +27,7 @@ |
#include "talk/app/webrtc/peerconnection.h" |
+#include <algorithm> |
#include <vector> |
#include <cctype> // for isdigit |
@@ -36,6 +37,7 @@ |
#include "talk/app/webrtc/jsepsessiondescription.h" |
#include "talk/app/webrtc/mediaconstraintsinterface.h" |
#include "talk/app/webrtc/mediastream.h" |
+#include "talk/app/webrtc/mediastreamobserver.h" |
#include "talk/app/webrtc/mediastreamproxy.h" |
#include "talk/app/webrtc/mediastreamtrackproxy.h" |
#include "talk/app/webrtc/remoteaudiosource.h" |
@@ -733,48 +735,22 @@ bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { |
} |
local_streams_->AddStream(local_stream); |
+ MediaStreamObserver* observer = new MediaStreamObserver(local_stream); |
+ observer->SignalAudioTrackAdded.connect(this, |
+ &PeerConnection::OnAudioTrackAdded); |
+ observer->SignalAudioTrackRemoved.connect( |
+ this, &PeerConnection::OnAudioTrackRemoved); |
+ observer->SignalVideoTrackAdded.connect(this, |
+ &PeerConnection::OnVideoTrackAdded); |
+ observer->SignalVideoTrackRemoved.connect( |
+ this, &PeerConnection::OnVideoTrackRemoved); |
+ stream_observers_.push_back(rtc::scoped_ptr<MediaStreamObserver>(observer)); |
for (const auto& track : local_stream->GetAudioTracks()) { |
- auto sender = FindSenderForTrack(track.get()); |
- if (sender == senders_.end()) { |
- // Normal case; we've never seen this track before. |
- AudioRtpSender* new_sender = new AudioRtpSender( |
- track.get(), local_stream->label(), session_.get(), stats_.get()); |
- senders_.push_back(new_sender); |
- // If the sender has already been configured in SDP, we call SetSsrc, |
- // which will connect the sender to the underlying transport. This can |
- // occur if a local session description that contains the ID of the sender |
- // is set before AddStream is called. It can also occur if the local |
- // session description is not changed and RemoveStream is called, and |
- // later AddStream is called again with the same stream. |
- const TrackInfo* track_info = FindTrackInfo( |
- local_audio_tracks_, local_stream->label(), track->id()); |
- if (track_info) { |
- new_sender->SetSsrc(track_info->ssrc); |
- } |
- } else { |
- // We already have a sender for this track, so just change the stream_id |
- // so that it's correct in the next call to CreateOffer. |
- (*sender)->set_stream_id(local_stream->label()); |
- } |
+ OnAudioTrackAdded(track.get(), local_stream); |
} |
for (const auto& track : local_stream->GetVideoTracks()) { |
- auto sender = FindSenderForTrack(track.get()); |
- if (sender == senders_.end()) { |
- // Normal case; we've never seen this track before. |
- VideoRtpSender* new_sender = new VideoRtpSender( |
- track.get(), local_stream->label(), session_.get()); |
- senders_.push_back(new_sender); |
- const TrackInfo* track_info = FindTrackInfo( |
- local_video_tracks_, local_stream->label(), track->id()); |
- if (track_info) { |
- new_sender->SetSsrc(track_info->ssrc); |
- } |
- } else { |
- // We already have a sender for this track, so just change the stream_id |
- // so that it's correct in the next call to CreateOffer. |
- (*sender)->set_stream_id(local_stream->label()); |
- } |
+ OnVideoTrackAdded(track.get(), local_stream); |
} |
stats_->AddStream(local_stream); |
@@ -782,31 +758,24 @@ bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { |
return true; |
} |
-// TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around |
-// indefinitely, when we have unified plan SDP. |
void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { |
for (const auto& track : local_stream->GetAudioTracks()) { |
- auto sender = FindSenderForTrack(track.get()); |
- if (sender == senders_.end()) { |
- LOG(LS_WARNING) << "RtpSender for track with id " << track->id() |
- << " doesn't exist."; |
- continue; |
- } |
- (*sender)->Stop(); |
- senders_.erase(sender); |
+ OnAudioTrackRemoved(track.get(), local_stream); |
} |
for (const auto& track : local_stream->GetVideoTracks()) { |
- auto sender = FindSenderForTrack(track.get()); |
- if (sender == senders_.end()) { |
- LOG(LS_WARNING) << "RtpSender for track with id " << track->id() |
- << " doesn't exist."; |
- continue; |
- } |
- (*sender)->Stop(); |
- senders_.erase(sender); |
+ OnVideoTrackRemoved(track.get(), local_stream); |
} |
local_streams_->RemoveStream(local_stream); |
+ auto it = std::find_if( |
+ stream_observers_.begin(), stream_observers_.end(), |
+ [local_stream]( |
+ const rtc::scoped_ptr<MediaStreamObserver>& observer) -> bool { |
pthatcher1
2015/12/08 21:31:05
I think you can leave off the "-> bool" (it can be
Taylor Brandstetter
2015/12/09 00:36:02
Done.
|
+ return observer->stream()->label().compare(local_stream->label()) == 0; |
+ }); |
+ if (it != stream_observers_.end()) { |
+ stream_observers_.erase(it); |
+ } |
pthatcher1
2015/12/08 21:31:05
I think you can use std::remove_if to save a few l
Taylor Brandstetter
2015/12/09 00:36:02
Done.
|
if (IsClosed()) { |
return; |
@@ -1409,6 +1378,78 @@ void PeerConnection::ChangeSignalingState( |
observer_->OnStateChange(PeerConnectionObserver::kSignalingState); |
} |
+void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track, |
+ MediaStreamInterface* stream) { |
+ auto sender = FindSenderForTrack(track); |
+ if (sender == senders_.end()) { |
pthatcher1
2015/12/08 21:31:05
Might as well use an early return, here and in OnV
Taylor Brandstetter
2015/12/09 00:36:02
Done.
|
+ // Normal case; we've never seen this track before. |
+ AudioRtpSender* new_sender = new AudioRtpSender( |
+ track, stream->label(), session_.get(), stats_.get()); |
+ senders_.push_back(new_sender); |
+ // If the sender has already been configured in SDP, we call SetSsrc, |
+ // which will connect the sender to the underlying transport. This can |
+ // occur if a local session description that contains the ID of the sender |
+ // is set before AddStream is called. It can also occur if the local |
+ // session description is not changed and RemoveStream is called, and |
+ // later AddStream is called again with the same stream. |
+ const TrackInfo* track_info = |
+ FindTrackInfo(local_audio_tracks_, stream->label(), track->id()); |
+ if (track_info) { |
+ new_sender->SetSsrc(track_info->ssrc); |
+ } |
+ } else { |
+ // We already have a sender for this track, so just change the stream_id |
+ // so that it's correct in the next call to CreateOffer. |
+ (*sender)->set_stream_id(stream->label()); |
+ } |
+} |
+ |
+// TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around |
+// indefinitely, when we have unified plan SDP. |
+void PeerConnection::OnAudioTrackRemoved(AudioTrackInterface* track, |
+ MediaStreamInterface* stream) { |
+ auto sender = FindSenderForTrack(track); |
+ if (sender == senders_.end()) { |
+ LOG(LS_WARNING) << "RtpSender for track with id " << track->id() |
+ << " doesn't exist."; |
+ return; |
+ } |
+ (*sender)->Stop(); |
+ senders_.erase(sender); |
+} |
+ |
+void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track, |
+ MediaStreamInterface* stream) { |
+ auto sender = FindSenderForTrack(track); |
+ if (sender == senders_.end()) { |
+ // Normal case; we've never seen this track before. |
+ VideoRtpSender* new_sender = |
+ new VideoRtpSender(track, stream->label(), session_.get()); |
+ senders_.push_back(new_sender); |
+ const TrackInfo* track_info = |
+ FindTrackInfo(local_video_tracks_, stream->label(), track->id()); |
+ if (track_info) { |
+ new_sender->SetSsrc(track_info->ssrc); |
+ } |
+ } else { |
+ // We already have a sender for this track, so just change the stream_id |
+ // so that it's correct in the next call to CreateOffer. |
+ (*sender)->set_stream_id(stream->label()); |
+ } |
+} |
+ |
+void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track, |
+ MediaStreamInterface* stream) { |
+ auto sender = FindSenderForTrack(track); |
+ if (sender == senders_.end()) { |
+ LOG(LS_WARNING) << "RtpSender for track with id " << track->id() |
+ << " doesn't exist."; |
+ return; |
+ } |
+ (*sender)->Stop(); |
+ senders_.erase(sender); |
+} |
+ |
void PeerConnection::PostSetSessionDescriptionFailure( |
SetSessionDescriptionObserver* observer, |
const std::string& error) { |