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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 #include "webrtc/base/stringencode.h" | 52 #include "webrtc/base/stringencode.h" |
53 #include "webrtc/base/stringutils.h" | 53 #include "webrtc/base/stringutils.h" |
54 #include "webrtc/system_wrappers/interface/field_trial.h" | 54 #include "webrtc/system_wrappers/interface/field_trial.h" |
55 | 55 |
56 namespace { | 56 namespace { |
57 | 57 |
58 using webrtc::DataChannel; | 58 using webrtc::DataChannel; |
59 using webrtc::MediaConstraintsInterface; | 59 using webrtc::MediaConstraintsInterface; |
60 using webrtc::MediaStreamInterface; | 60 using webrtc::MediaStreamInterface; |
61 using webrtc::PeerConnectionInterface; | 61 using webrtc::PeerConnectionInterface; |
62 using webrtc::RtpSenderInterface; | |
62 using webrtc::StreamCollection; | 63 using webrtc::StreamCollection; |
63 using webrtc::StunConfigurations; | 64 using webrtc::StunConfigurations; |
64 using webrtc::TurnConfigurations; | 65 using webrtc::TurnConfigurations; |
65 typedef webrtc::PortAllocatorFactoryInterface::StunConfiguration | 66 typedef webrtc::PortAllocatorFactoryInterface::StunConfiguration |
66 StunConfiguration; | 67 StunConfiguration; |
67 typedef webrtc::PortAllocatorFactoryInterface::TurnConfiguration | 68 typedef webrtc::PortAllocatorFactoryInterface::TurnConfiguration |
68 TurnConfiguration; | 69 TurnConfiguration; |
69 | 70 |
70 static const char kDefaultStreamLabel[] = "default"; | 71 static const char kDefaultStreamLabel[] = "default"; |
71 static const char kDefaultAudioTrackLabel[] = "defaulta0"; | 72 static const char kDefaultAudioTrackLabel[] = "defaulta0"; |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 : std::vector<cricket::StreamParams>(); | 359 : std::vector<cricket::StreamParams>(); |
359 } | 360 } |
360 | 361 |
361 bool IsValidOfferToReceiveMedia(int value) { | 362 bool IsValidOfferToReceiveMedia(int value) { |
362 typedef PeerConnectionInterface::RTCOfferAnswerOptions Options; | 363 typedef PeerConnectionInterface::RTCOfferAnswerOptions Options; |
363 return (value >= Options::kUndefined) && | 364 return (value >= Options::kUndefined) && |
364 (value <= Options::kMaxOfferToReceiveMedia); | 365 (value <= Options::kMaxOfferToReceiveMedia); |
365 } | 366 } |
366 | 367 |
367 // Add the stream and RTP data channel info to |session_options|. | 368 // Add the stream and RTP data channel info to |session_options|. |
368 void SetStreams(cricket::MediaSessionOptions* session_options, | 369 void AddSendStreams( |
369 rtc::scoped_refptr<StreamCollection> streams, | 370 cricket::MediaSessionOptions* session_options, |
370 const std::map<std::string, rtc::scoped_refptr<DataChannel>>& | 371 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders, |
371 rtp_data_channels) { | 372 const std::map<std::string, rtc::scoped_refptr<DataChannel>>& |
373 rtp_data_channels) { | |
372 session_options->streams.clear(); | 374 session_options->streams.clear(); |
373 if (streams != nullptr) { | 375 for (const auto& sender : senders) { |
374 for (size_t i = 0; i < streams->count(); ++i) { | 376 // Add each sender to the MediaSessionOptions. |
375 MediaStreamInterface* stream = streams->at(i); | 377 cricket::MediaType type; |
376 // For each audio track in the stream, add it to the MediaSessionOptions. | 378 if (sender->kind() == "audio") { |
pthatcher1
2015/10/20 17:42:49
We should use a named constant for "audio" and "vi
Taylor Brandstetter
2015/10/21 00:22:08
Done.
| |
377 for (const auto& track : stream->GetAudioTracks()) { | 379 type = cricket::MEDIA_TYPE_AUDIO; |
378 session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, track->id(), | 380 } else if (sender->kind() == "video") { |
379 stream->label()); | 381 type = cricket::MEDIA_TYPE_VIDEO; |
380 } | 382 } else { |
381 // For each video track in the stream, add it to the MediaSessionOptions. | 383 RTC_DCHECK(false && "Invalid 'kind' for RtpSender."); |
382 for (const auto& track : stream->GetVideoTracks()) { | 384 continue; |
383 session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, track->id(), | |
384 stream->label()); | |
385 } | |
386 } | 385 } |
386 session_options->AddSendStream(type, sender->id(), sender->stream_id()); | |
387 } | 387 } |
388 | 388 |
389 // Check for data channels. | 389 // Check for data channels. |
390 for (const auto& kv : rtp_data_channels) { | 390 for (const auto& kv : rtp_data_channels) { |
391 const DataChannel* channel = kv.second; | 391 const DataChannel* channel = kv.second; |
392 if (channel->state() == DataChannel::kConnecting || | 392 if (channel->state() == DataChannel::kConnecting || |
393 channel->state() == DataChannel::kOpen) { | 393 channel->state() == DataChannel::kOpen) { |
394 // |streamid| and |sync_label| are both set to the DataChannel label | 394 // |streamid| and |sync_label| are both set to the DataChannel label |
395 // here so they can be signaled the same way as MediaStreams and Tracks. | 395 // here so they can be signaled the same way as MediaStreams and Tracks. |
396 // For MediaStreams, the sync_label is the MediaStream label and the | 396 // For MediaStreams, the sync_label is the MediaStream label and the |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
676 rtc::scoped_refptr<StreamCollectionInterface> | 676 rtc::scoped_refptr<StreamCollectionInterface> |
677 PeerConnection::local_streams() { | 677 PeerConnection::local_streams() { |
678 return local_streams_; | 678 return local_streams_; |
679 } | 679 } |
680 | 680 |
681 rtc::scoped_refptr<StreamCollectionInterface> | 681 rtc::scoped_refptr<StreamCollectionInterface> |
682 PeerConnection::remote_streams() { | 682 PeerConnection::remote_streams() { |
683 return remote_streams_; | 683 return remote_streams_; |
684 } | 684 } |
685 | 685 |
686 // TODO(deadbeef): Create RtpSenders immediately here, even if local | |
687 // description hasn't yet been set. | |
688 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { | 686 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { |
689 if (IsClosed()) { | 687 if (IsClosed()) { |
690 return false; | 688 return false; |
691 } | 689 } |
692 if (!CanAddLocalMediaStream(local_streams_, local_stream)) { | 690 if (!CanAddLocalMediaStream(local_streams_, local_stream)) { |
693 return false; | 691 return false; |
694 } | 692 } |
695 | 693 |
696 local_streams_->AddStream(local_stream); | 694 local_streams_->AddStream(local_stream); |
697 | 695 |
698 // Find tracks that have already been configured in SDP. This can occur if a | 696 // Note: If the sender has already been configured in SDP, we call SetSsrc, |
699 // local session description that contains the MSID of these tracks is set | 697 // which will connect the sender to the underlying transport. This can occur |
700 // before AddLocalStream is called. It can also occur if the local session | 698 // if a local session description that contains the ID of the sender is set |
701 // description is not changed and RemoveLocalStream is called and later | 699 // before AddStream is called. It can also occur if the local session |
702 // AddLocalStream is called again with the same stream. | 700 // description is not changed and RemoveStream is called, and later |
701 // AddStream is called again with the same stream. | |
pthatcher1
2015/10/20 17:42:49
I'm a little lost as to how this comment matches t
Taylor Brandstetter
2015/10/21 00:22:08
"Already configured in SDP" isn't the same as "alr
| |
703 for (const auto& track : local_stream->GetAudioTracks()) { | 702 for (const auto& track : local_stream->GetAudioTracks()) { |
704 const TrackInfo* track_info = | 703 auto sender = FindSenderForTrack(track.get()); |
705 FindTrackInfo(local_audio_tracks_, local_stream->label(), track->id()); | 704 if (sender == senders_.end()) { |
706 if (track_info) { | 705 // Normal case; we've never seen this track before. |
707 CreateAudioSender(local_stream, track.get(), track_info->ssrc); | 706 AudioRtpSender* new_sender = new AudioRtpSender( |
707 track.get(), local_stream->label(), session_.get(), stats_.get()); | |
708 senders_.push_back(new_sender); | |
709 const TrackInfo* track_info = FindTrackInfo( | |
710 local_audio_tracks_, local_stream->label(), track->id()); | |
711 if (track_info) { | |
712 new_sender->SetSsrc(track_info->ssrc); | |
713 } | |
714 } else { | |
715 // We already have a sender for this track, so just change the stream_id | |
716 // so that it's correct in the next call to CreateOffer. | |
717 (*sender)->set_stream_id(local_stream->label()); | |
pthatcher1
2015/10/20 17:42:49
Should this method be set_stream_label?
Taylor Brandstetter
2015/10/21 00:22:08
Since in the W3C spec it's called an "id", I figur
| |
708 } | 718 } |
709 } | 719 } |
710 for (const auto& track : local_stream->GetVideoTracks()) { | 720 for (const auto& track : local_stream->GetVideoTracks()) { |
711 const TrackInfo* track_info = | 721 auto sender = FindSenderForTrack(track.get()); |
712 FindTrackInfo(local_video_tracks_, local_stream->label(), track->id()); | 722 if (sender == senders_.end()) { |
713 if (track_info) { | 723 // Normal case; we've never seen this track before. |
714 CreateVideoSender(local_stream, track.get(), track_info->ssrc); | 724 VideoRtpSender* new_sender = new VideoRtpSender( |
725 track.get(), local_stream->label(), session_.get()); | |
726 senders_.push_back(new_sender); | |
727 const TrackInfo* track_info = FindTrackInfo( | |
728 local_video_tracks_, local_stream->label(), track->id()); | |
729 if (track_info) { | |
730 new_sender->SetSsrc(track_info->ssrc); | |
731 } | |
732 } else { | |
733 // We already have a sender for this track, so just change the stream_id | |
734 // so that it's correct in the next call to CreateOffer. | |
735 (*sender)->set_stream_id(local_stream->label()); | |
715 } | 736 } |
716 } | 737 } |
717 | 738 |
718 stats_->AddStream(local_stream); | 739 stats_->AddStream(local_stream); |
719 observer_->OnRenegotiationNeeded(); | 740 observer_->OnRenegotiationNeeded(); |
720 return true; | 741 return true; |
721 } | 742 } |
722 | 743 |
723 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around | 744 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around |
724 // indefinitely. | 745 // indefinitely, when we have unified plan SDP. |
725 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { | 746 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { |
726 for (const auto& track : local_stream->GetAudioTracks()) { | 747 for (const auto& track : local_stream->GetAudioTracks()) { |
727 const TrackInfo* track_info = | 748 auto sender = FindSenderForTrack(track.get()); |
728 FindTrackInfo(local_audio_tracks_, local_stream->label(), track->id()); | 749 if (sender == senders_.end()) { |
729 if (track_info) { | 750 LOG(LS_WARNING) << "RtpSender for track with id " << track->id() |
730 DestroyAudioSender(local_stream, track.get(), track_info->ssrc); | 751 << " doesn't exist."; |
752 continue; | |
731 } | 753 } |
754 (*sender)->Stop(); | |
755 senders_.erase(sender); | |
732 } | 756 } |
733 for (const auto& track : local_stream->GetVideoTracks()) { | 757 for (const auto& track : local_stream->GetVideoTracks()) { |
734 const TrackInfo* track_info = | 758 auto sender = FindSenderForTrack(track.get()); |
735 FindTrackInfo(local_video_tracks_, local_stream->label(), track->id()); | 759 if (sender == senders_.end()) { |
736 if (track_info) { | 760 LOG(LS_WARNING) << "RtpSender for track with id " << track->id() |
737 DestroyVideoSender(local_stream, track.get()); | 761 << " doesn't exist."; |
762 continue; | |
738 } | 763 } |
764 (*sender)->Stop(); | |
765 senders_.erase(sender); | |
739 } | 766 } |
740 | 767 |
741 local_streams_->RemoveStream(local_stream); | 768 local_streams_->RemoveStream(local_stream); |
742 | 769 |
743 if (IsClosed()) { | 770 if (IsClosed()) { |
744 return; | 771 return; |
745 } | 772 } |
746 observer_->OnRenegotiationNeeded(); | 773 observer_->OnRenegotiationNeeded(); |
747 } | 774 } |
748 | 775 |
(...skipping 10 matching lines...) Expand all Loading... | |
759 | 786 |
760 rtc::scoped_refptr<DtmfSenderInterface> sender( | 787 rtc::scoped_refptr<DtmfSenderInterface> sender( |
761 DtmfSender::Create(track, signaling_thread(), session_.get())); | 788 DtmfSender::Create(track, signaling_thread(), session_.get())); |
762 if (!sender.get()) { | 789 if (!sender.get()) { |
763 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; | 790 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; |
764 return NULL; | 791 return NULL; |
765 } | 792 } |
766 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); | 793 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); |
767 } | 794 } |
768 | 795 |
796 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender( | |
797 const std::string& kind) { | |
798 RtpSenderInterface* new_sender; | |
799 if (kind == "audio") { | |
pthatcher1
2015/10/20 17:42:49
Same here with named constants.
Taylor Brandstetter
2015/10/21 00:22:08
Done.
| |
800 new_sender = new AudioRtpSender(session_.get(), stats_.get()); | |
801 } else if (kind == "video") { | |
802 new_sender = new VideoRtpSender(session_.get()); | |
803 } else { | |
804 return rtc::scoped_refptr<RtpSenderInterface>(); | |
805 } | |
806 senders_.push_back(new_sender); | |
807 return RtpSenderProxy::Create(signaling_thread(), new_sender); | |
808 } | |
809 | |
769 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders() | 810 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders() |
770 const { | 811 const { |
771 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders; | 812 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders; |
772 for (const auto& sender : senders_) { | 813 for (const auto& sender : senders_) { |
773 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get())); | 814 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get())); |
774 } | 815 } |
775 return senders; | 816 return senders; |
776 } | 817 } |
777 | 818 |
778 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> | 819 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1275 auto it = FindReceiverForTrack(video_track); | 1316 auto it = FindReceiverForTrack(video_track); |
1276 if (it == receivers_.end()) { | 1317 if (it == receivers_.end()) { |
1277 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() | 1318 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() |
1278 << " doesn't exist."; | 1319 << " doesn't exist."; |
1279 } else { | 1320 } else { |
1280 (*it)->Stop(); | 1321 (*it)->Stop(); |
1281 receivers_.erase(it); | 1322 receivers_.erase(it); |
1282 } | 1323 } |
1283 } | 1324 } |
1284 | 1325 |
1285 void PeerConnection::CreateAudioSender(MediaStreamInterface* stream, | |
1286 AudioTrackInterface* audio_track, | |
1287 uint32_t ssrc) { | |
1288 senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get())); | |
1289 stats_->AddLocalAudioTrack(audio_track, ssrc); | |
1290 } | |
1291 | |
1292 void PeerConnection::CreateVideoSender(MediaStreamInterface* stream, | |
1293 VideoTrackInterface* video_track, | |
1294 uint32_t ssrc) { | |
1295 senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get())); | |
1296 } | |
1297 | |
1298 // TODO(deadbeef): Keep RtpSenders around even if track goes away in local | |
1299 // description. | |
1300 void PeerConnection::DestroyAudioSender(MediaStreamInterface* stream, | |
1301 AudioTrackInterface* audio_track, | |
1302 uint32_t ssrc) { | |
1303 auto it = FindSenderForTrack(audio_track); | |
1304 if (it == senders_.end()) { | |
1305 LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id() | |
1306 << " doesn't exist."; | |
1307 return; | |
1308 } else { | |
1309 (*it)->Stop(); | |
1310 senders_.erase(it); | |
1311 } | |
1312 stats_->RemoveLocalAudioTrack(audio_track, ssrc); | |
1313 } | |
1314 | |
1315 void PeerConnection::DestroyVideoSender(MediaStreamInterface* stream, | |
1316 VideoTrackInterface* video_track) { | |
1317 auto it = FindSenderForTrack(video_track); | |
1318 if (it == senders_.end()) { | |
1319 LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id() | |
1320 << " doesn't exist."; | |
1321 return; | |
1322 } else { | |
1323 (*it)->Stop(); | |
1324 senders_.erase(it); | |
1325 } | |
1326 } | |
1327 | |
1328 void PeerConnection::OnIceConnectionChange( | 1326 void PeerConnection::OnIceConnectionChange( |
1329 PeerConnectionInterface::IceConnectionState new_state) { | 1327 PeerConnectionInterface::IceConnectionState new_state) { |
1330 RTC_DCHECK(signaling_thread()->IsCurrent()); | 1328 RTC_DCHECK(signaling_thread()->IsCurrent()); |
1331 // After transitioning to "closed", ignore any additional states from | 1329 // After transitioning to "closed", ignore any additional states from |
1332 // WebRtcSession (such as "disconnected"). | 1330 // WebRtcSession (such as "disconnected"). |
1333 if (IsClosed()) { | 1331 if (IsClosed()) { |
1334 return; | 1332 return; |
1335 } | 1333 } |
1336 ice_connection_state_ = new_state; | 1334 ice_connection_state_ = new_state; |
1337 observer_->OnIceConnectionChange(ice_connection_state_); | 1335 observer_->OnIceConnectionChange(ice_connection_state_); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1389 CreateSessionDescriptionObserver* observer, | 1387 CreateSessionDescriptionObserver* observer, |
1390 const std::string& error) { | 1388 const std::string& error) { |
1391 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); | 1389 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); |
1392 msg->error = error; | 1390 msg->error = error; |
1393 signaling_thread()->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg); | 1391 signaling_thread()->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg); |
1394 } | 1392 } |
1395 | 1393 |
1396 bool PeerConnection::GetOptionsForOffer( | 1394 bool PeerConnection::GetOptionsForOffer( |
1397 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, | 1395 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, |
1398 cricket::MediaSessionOptions* session_options) { | 1396 cricket::MediaSessionOptions* session_options) { |
1399 SetStreams(session_options, local_streams_, rtp_data_channels_); | 1397 AddSendStreams(session_options, senders_, rtp_data_channels_); |
1400 | 1398 |
1401 if (!ConvertRtcOptionsForOffer(rtc_options, session_options)) { | 1399 if (!ConvertRtcOptionsForOffer(rtc_options, session_options)) { |
1402 return false; | 1400 return false; |
1403 } | 1401 } |
1404 | 1402 |
1405 if (session_->data_channel_type() == cricket::DCT_SCTP && HasDataChannels()) { | 1403 if (session_->data_channel_type() == cricket::DCT_SCTP && HasDataChannels()) { |
1406 session_options->data_channel_type = cricket::DCT_SCTP; | 1404 session_options->data_channel_type = cricket::DCT_SCTP; |
1407 } | 1405 } |
1408 return true; | 1406 return true; |
1409 } | 1407 } |
1410 | 1408 |
1411 bool PeerConnection::GetOptionsForAnswer( | 1409 bool PeerConnection::GetOptionsForAnswer( |
1412 const MediaConstraintsInterface* constraints, | 1410 const MediaConstraintsInterface* constraints, |
1413 cricket::MediaSessionOptions* session_options) { | 1411 cricket::MediaSessionOptions* session_options) { |
1414 SetStreams(session_options, local_streams_, rtp_data_channels_); | 1412 AddSendStreams(session_options, senders_, rtp_data_channels_); |
1415 session_options->recv_audio = false; | 1413 session_options->recv_audio = false; |
1416 session_options->recv_video = false; | 1414 session_options->recv_video = false; |
1417 | 1415 |
1418 if (!ParseConstraintsForAnswer(constraints, session_options)) { | 1416 if (!ParseConstraintsForAnswer(constraints, session_options)) { |
1419 return false; | 1417 return false; |
1420 } | 1418 } |
1421 | 1419 |
1422 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams | 1420 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams |
1423 // are not signaled in the SDP so does not go through that path and must be | 1421 // are not signaled in the SDP so does not go through that path and must be |
1424 // handled here. | 1422 // handled here. |
1425 if (session_->data_channel_type() == cricket::DCT_SCTP) { | 1423 if (session_->data_channel_type() == cricket::DCT_SCTP) { |
1426 session_options->data_channel_type = cricket::DCT_SCTP; | 1424 session_options->data_channel_type = cricket::DCT_SCTP; |
1427 } | 1425 } |
1428 return true; | 1426 return true; |
1429 } | 1427 } |
1430 | 1428 |
1431 void PeerConnection::UpdateRemoteStreamsList( | 1429 void PeerConnection::UpdateRemoteStreamsList( |
1432 const cricket::StreamParamsVec& streams, | 1430 const cricket::StreamParamsVec& streams, |
1433 cricket::MediaType media_type, | 1431 cricket::MediaType media_type, |
1434 StreamCollection* new_streams) { | 1432 StreamCollection* new_streams) { |
1435 TrackInfos* current_tracks = GetRemoteTracks(media_type); | 1433 TrackInfos* current_tracks = GetRemoteTracks(media_type); |
1436 | 1434 |
1437 // Find removed tracks. I.e., tracks where the track id or ssrc don't match | 1435 // Find removed tracks. I.e., tracks where the track id or ssrc don't match |
1438 // the | 1436 // the new StreamParam. |
1439 // new StreamParam. | |
1440 auto track_it = current_tracks->begin(); | 1437 auto track_it = current_tracks->begin(); |
1441 while (track_it != current_tracks->end()) { | 1438 while (track_it != current_tracks->end()) { |
1442 const TrackInfo& info = *track_it; | 1439 const TrackInfo& info = *track_it; |
1443 const cricket::StreamParams* params = | 1440 const cricket::StreamParams* params = |
1444 cricket::GetStreamBySsrc(streams, info.ssrc); | 1441 cricket::GetStreamBySsrc(streams, info.ssrc); |
1445 if (!params || params->id != info.track_id) { | 1442 if (!params || params->id != info.track_id) { |
1446 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type); | 1443 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type); |
1447 track_it = current_tracks->erase(track_it); | 1444 track_it = current_tracks->erase(track_it); |
1448 } else { | 1445 } else { |
1449 ++track_it; | 1446 ++track_it; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1630 if (!track_info) { | 1627 if (!track_info) { |
1631 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc)); | 1628 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc)); |
1632 OnLocalTrackSeen(stream_label, track_id, params.first_ssrc(), media_type); | 1629 OnLocalTrackSeen(stream_label, track_id, params.first_ssrc(), media_type); |
1633 } | 1630 } |
1634 } | 1631 } |
1635 } | 1632 } |
1636 | 1633 |
1637 void PeerConnection::OnLocalTrackSeen(const std::string& stream_label, | 1634 void PeerConnection::OnLocalTrackSeen(const std::string& stream_label, |
1638 const std::string& track_id, | 1635 const std::string& track_id, |
1639 uint32_t ssrc, | 1636 uint32_t ssrc, |
1640 cricket::MediaType media_type) { | 1637 cricket::MediaType media_type) { |
pthatcher1
2015/10/20 17:42:49
Should we call this OnSenderAddedToSessionDescript
Taylor Brandstetter
2015/10/21 00:22:08
Well, then it would be inconsistent with OnRemoteT
| |
1641 MediaStreamInterface* stream = local_streams_->find(stream_label); | 1638 RtpSenderInterface* sender = FindSenderById(track_id); |
pthatcher1
2015/10/20 17:42:49
Should we match the media_type/kind when finding s
Taylor Brandstetter
2015/10/21 00:22:08
Then we wouldn't be able to tell "unknown sender"
| |
1642 if (!stream) { | 1639 if (!sender) { |
1643 LOG(LS_WARNING) << "An unknown local MediaStream with label " | 1640 LOG(LS_WARNING) << "An unknown RtpSender with id " << track_id |
1644 << stream_label << " has been configured."; | 1641 << " has been configured in the local description."; |
1645 return; | 1642 return; |
1646 } | 1643 } |
1647 | 1644 |
1648 if (media_type == cricket::MEDIA_TYPE_AUDIO) { | 1645 if (!((media_type == cricket::MEDIA_TYPE_AUDIO && |
1649 AudioTrackInterface* audio_track = stream->FindAudioTrack(track_id); | 1646 sender->kind() == "audio") || |
1650 if (!audio_track) { | 1647 (media_type == cricket::MEDIA_TYPE_VIDEO && |
1651 LOG(LS_WARNING) << "An unknown local AudioTrack with id , " << track_id | 1648 sender->kind() == "video"))) { |
1652 << " has been configured."; | 1649 LOG(LS_WARNING) << "An RtpSender has been configured in the local" |
1653 return; | 1650 << " description with an unexpected media type."; |
1654 } | 1651 RTC_DCHECK(false && "Invalid media type."); |
pthatcher1
2015/10/20 17:42:49
This is an error from the application or the javas
Taylor Brandstetter
2015/10/21 00:22:08
DCHECKS only do anything in a debug builds (hence
pthatcher1
2015/10/22 07:34:13
But do we still want to allow bad JS to crash the
Taylor Brandstetter
2015/10/22 19:26:42
Oh, that's a good point. Ok, it's removed.
| |
1655 CreateAudioSender(stream, audio_track, ssrc); | 1652 return; |
1656 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { | |
1657 VideoTrackInterface* video_track = stream->FindVideoTrack(track_id); | |
1658 if (!video_track) { | |
1659 LOG(LS_WARNING) << "An unknown local VideoTrack with id , " << track_id | |
1660 << " has been configured."; | |
1661 return; | |
1662 } | |
1663 CreateVideoSender(stream, video_track, ssrc); | |
1664 } else { | |
1665 RTC_DCHECK(false && "Invalid media type"); | |
1666 } | 1653 } |
1654 | |
1655 sender->set_stream_id(stream_label); | |
1656 sender->SetSsrc(ssrc); | |
1667 } | 1657 } |
1668 | 1658 |
1669 void PeerConnection::OnLocalTrackRemoved(const std::string& stream_label, | 1659 void PeerConnection::OnLocalTrackRemoved(const std::string& stream_label, |
1670 const std::string& track_id, | 1660 const std::string& track_id, |
1671 uint32_t ssrc, | 1661 uint32_t ssrc, |
1672 cricket::MediaType media_type) { | 1662 cricket::MediaType media_type) { |
pthatcher1
2015/10/20 17:42:49
Should we call this OnSenderRemovedFromSessionDesc
| |
1673 MediaStreamInterface* stream = local_streams_->find(stream_label); | 1663 RtpSenderInterface* sender = FindSenderById(track_id); |
1674 if (!stream) { | 1664 if (!sender) { |
1675 // This is the normal case. I.e., RemoveLocalStream has been called and the | 1665 // This is the normal case. I.e., RemoveStream has been called and the |
1676 // SessionDescriptions has been renegotiated. | 1666 // SessionDescriptions has been renegotiated. |
1677 return; | 1667 return; |
1678 } | 1668 } |
1679 // A track has been removed from the SessionDescription but the MediaStream | 1669 |
1680 // is still associated with PeerConnection. This only occurs if the SDP | 1670 // A sender has been removed from the SessionDescription but it's still |
1681 // doesn't match with the calls to AddLocalStream and RemoveLocalStream. | 1671 // associated with the PeerConnection. This only occurs if the SDP doesn't |
1682 if (media_type == cricket::MEDIA_TYPE_AUDIO) { | 1672 // match with the calls to CreateSender, AddStream and RemoveStream. |
1683 AudioTrackInterface* audio_track = stream->FindAudioTrack(track_id); | 1673 if (!((media_type == cricket::MEDIA_TYPE_AUDIO && |
1684 if (!audio_track) { | 1674 sender->kind() == "audio") || |
pthatcher1
2015/10/20 17:42:49
Can we change the sender->kind() to be a cricket::
Taylor Brandstetter
2015/10/21 00:22:08
Done.
| |
1685 return; | 1675 (media_type == cricket::MEDIA_TYPE_VIDEO && |
1686 } | 1676 sender->kind() == "video"))) { |
1687 DestroyAudioSender(stream, audio_track, ssrc); | 1677 LOG(LS_WARNING) << "An RtpSender has been configured in the local" |
1688 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { | 1678 << " description with an unexpected media type."; |
1689 VideoTrackInterface* video_track = stream->FindVideoTrack(track_id); | |
1690 if (!video_track) { | |
1691 return; | |
1692 } | |
1693 DestroyVideoSender(stream, video_track); | |
1694 } else { | |
1695 RTC_DCHECK(false && "Invalid media type."); | 1679 RTC_DCHECK(false && "Invalid media type."); |
1680 return; | |
1696 } | 1681 } |
1682 | |
1683 sender->SetSsrc(0); | |
1697 } | 1684 } |
1698 | 1685 |
1699 void PeerConnection::UpdateLocalRtpDataChannels( | 1686 void PeerConnection::UpdateLocalRtpDataChannels( |
1700 const cricket::StreamParamsVec& streams) { | 1687 const cricket::StreamParamsVec& streams) { |
1701 std::vector<std::string> existing_channels; | 1688 std::vector<std::string> existing_channels; |
1702 | 1689 |
1703 // Find new and active data channels. | 1690 // Find new and active data channels. |
1704 for (const cricket::StreamParams& params : streams) { | 1691 for (const cricket::StreamParams& params : streams) { |
1705 // |it->sync_label| is actually the data channel label. The reason is that | 1692 // |it->sync_label| is actually the data channel label. The reason is that |
1706 // we use the same naming of data channels as we do for | 1693 // we use the same naming of data channels as we do for |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1904 InternalCreateDataChannel(label, &config)); | 1891 InternalCreateDataChannel(label, &config)); |
1905 if (!channel.get()) { | 1892 if (!channel.get()) { |
1906 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message."; | 1893 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message."; |
1907 return; | 1894 return; |
1908 } | 1895 } |
1909 | 1896 |
1910 observer_->OnDataChannel( | 1897 observer_->OnDataChannel( |
1911 DataChannelProxy::Create(signaling_thread(), channel)); | 1898 DataChannelProxy::Create(signaling_thread(), channel)); |
1912 } | 1899 } |
1913 | 1900 |
1901 RtpSenderInterface* PeerConnection::FindSenderById(const std::string& id) { | |
1902 auto it = | |
1903 std::find_if(senders_.begin(), senders_.end(), | |
1904 [id](const rtc::scoped_refptr<RtpSenderInterface>& sender) { | |
1905 return sender->id() == id; | |
1906 }); | |
1907 return it != senders_.end() ? it->get() : nullptr; | |
1908 } | |
1909 | |
1914 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator | 1910 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator |
1915 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) { | 1911 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) { |
1916 return std::find_if( | 1912 return std::find_if( |
1917 senders_.begin(), senders_.end(), | 1913 senders_.begin(), senders_.end(), |
1918 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) { | 1914 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) { |
1919 return sender->track() == track; | 1915 return sender->track() == track; |
1920 }); | 1916 }); |
1921 } | 1917 } |
1922 | 1918 |
1923 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator | 1919 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1961 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { | 1957 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { |
1962 for (const auto& channel : sctp_data_channels_) { | 1958 for (const auto& channel : sctp_data_channels_) { |
1963 if (channel->id() == sid) { | 1959 if (channel->id() == sid) { |
1964 return channel; | 1960 return channel; |
1965 } | 1961 } |
1966 } | 1962 } |
1967 return nullptr; | 1963 return nullptr; |
1968 } | 1964 } |
1969 | 1965 |
1970 } // namespace webrtc | 1966 } // namespace webrtc |
OLD | NEW |