Chromium Code Reviews| 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) { |