| Index: talk/app/webrtc/peerconnection.cc
|
| diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc
|
| index 83e29191c8a2ac1b5003e5f684d7755250f11dec..4132764cc85d8943c463c054561aec4ff569ea4b 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"
|
| @@ -740,48 +742,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);
|
| @@ -789,32 +765,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) {
|
| TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
|
| 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);
|
| + stream_observers_.erase(
|
| + std::remove_if(
|
| + stream_observers_.begin(), stream_observers_.end(),
|
| + [local_stream](const rtc::scoped_ptr<MediaStreamObserver>& observer) {
|
| + return observer->stream()->label().compare(local_stream->label()) ==
|
| + 0;
|
| + }),
|
| + stream_observers_.end());
|
|
|
| if (IsClosed()) {
|
| return;
|
| @@ -1428,6 +1396,80 @@ void PeerConnection::ChangeSignalingState(
|
| observer_->OnStateChange(PeerConnectionObserver::kSignalingState);
|
| }
|
|
|
| +void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track,
|
| + MediaStreamInterface* stream) {
|
| + auto sender = FindSenderForTrack(track);
|
| + if (sender != senders_.end()) {
|
| + // 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());
|
| + return;
|
| + }
|
| +
|
| + // 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);
|
| + }
|
| +}
|
| +
|
| +// 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()) {
|
| + // 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());
|
| + return;
|
| + }
|
| +
|
| + // 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);
|
| + }
|
| +}
|
| +
|
| +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) {
|
|
|