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

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

Issue 1413713003: Adding the ability to create an RtpSender without a track. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing patch conflicts. Created 5 years, 2 months 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/peerconnection_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,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 session_options->AddSendStream(sender->media_type(), sender->id(),
375 MediaStreamInterface* stream = streams->at(i); 377 sender->stream_id());
376 // For each audio track in the stream, add it to the MediaSessionOptions.
377 for (const auto& track : stream->GetAudioTracks()) {
378 session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, track->id(),
379 stream->label());
380 }
381 // For each video track in the stream, add it to the MediaSessionOptions.
382 for (const auto& track : stream->GetVideoTracks()) {
383 session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, track->id(),
384 stream->label());
385 }
386 }
387 } 378 }
388 379
389 // Check for data channels. 380 // Check for data channels.
390 for (const auto& kv : rtp_data_channels) { 381 for (const auto& kv : rtp_data_channels) {
391 const DataChannel* channel = kv.second; 382 const DataChannel* channel = kv.second;
392 if (channel->state() == DataChannel::kConnecting || 383 if (channel->state() == DataChannel::kConnecting ||
393 channel->state() == DataChannel::kOpen) { 384 channel->state() == DataChannel::kOpen) {
394 // |streamid| and |sync_label| are both set to the DataChannel label 385 // |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. 386 // 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 387 // For MediaStreams, the sync_label is the MediaStream label and the
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 rtc::scoped_refptr<StreamCollectionInterface> 652 rtc::scoped_refptr<StreamCollectionInterface>
662 PeerConnection::local_streams() { 653 PeerConnection::local_streams() {
663 return local_streams_; 654 return local_streams_;
664 } 655 }
665 656
666 rtc::scoped_refptr<StreamCollectionInterface> 657 rtc::scoped_refptr<StreamCollectionInterface>
667 PeerConnection::remote_streams() { 658 PeerConnection::remote_streams() {
668 return remote_streams_; 659 return remote_streams_;
669 } 660 }
670 661
671 // TODO(deadbeef): Create RtpSenders immediately here, even if local
672 // description hasn't yet been set.
673 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { 662 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
674 if (IsClosed()) { 663 if (IsClosed()) {
675 return false; 664 return false;
676 } 665 }
677 if (!CanAddLocalMediaStream(local_streams_, local_stream)) { 666 if (!CanAddLocalMediaStream(local_streams_, local_stream)) {
678 return false; 667 return false;
679 } 668 }
680 669
681 local_streams_->AddStream(local_stream); 670 local_streams_->AddStream(local_stream);
682 671
683 // Find tracks that have already been configured in SDP. This can occur if a
684 // local session description that contains the MSID of these tracks is set
685 // before AddLocalStream is called. It can also occur if the local session
686 // description is not changed and RemoveLocalStream is called and later
687 // AddLocalStream is called again with the same stream.
688 for (const auto& track : local_stream->GetAudioTracks()) { 672 for (const auto& track : local_stream->GetAudioTracks()) {
689 const TrackInfo* track_info = 673 auto sender = FindSenderForTrack(track.get());
690 FindTrackInfo(local_audio_tracks_, local_stream->label(), track->id()); 674 if (sender == senders_.end()) {
691 if (track_info) { 675 // Normal case; we've never seen this track before.
692 CreateAudioSender(local_stream, track.get(), track_info->ssrc); 676 AudioRtpSender* new_sender = new AudioRtpSender(
677 track.get(), local_stream->label(), session_.get(), stats_.get());
678 senders_.push_back(new_sender);
679 // If the sender has already been configured in SDP, we call SetSsrc,
680 // which will connect the sender to the underlying transport. This can
681 // occur if a local session description that contains the ID of the sender
682 // is set before AddStream is called. It can also occur if the local
683 // session description is not changed and RemoveStream is called, and
684 // later AddStream is called again with the same stream.
685 const TrackInfo* track_info = FindTrackInfo(
686 local_audio_tracks_, local_stream->label(), track->id());
687 if (track_info) {
688 new_sender->SetSsrc(track_info->ssrc);
689 }
690 } else {
691 // We already have a sender for this track, so just change the stream_id
692 // so that it's correct in the next call to CreateOffer.
693 (*sender)->set_stream_id(local_stream->label());
693 } 694 }
694 } 695 }
695 for (const auto& track : local_stream->GetVideoTracks()) { 696 for (const auto& track : local_stream->GetVideoTracks()) {
696 const TrackInfo* track_info = 697 auto sender = FindSenderForTrack(track.get());
697 FindTrackInfo(local_video_tracks_, local_stream->label(), track->id()); 698 if (sender == senders_.end()) {
698 if (track_info) { 699 // Normal case; we've never seen this track before.
699 CreateVideoSender(local_stream, track.get(), track_info->ssrc); 700 VideoRtpSender* new_sender = new VideoRtpSender(
701 track.get(), local_stream->label(), session_.get());
702 senders_.push_back(new_sender);
703 const TrackInfo* track_info = FindTrackInfo(
704 local_video_tracks_, local_stream->label(), track->id());
705 if (track_info) {
706 new_sender->SetSsrc(track_info->ssrc);
707 }
708 } else {
709 // We already have a sender for this track, so just change the stream_id
710 // so that it's correct in the next call to CreateOffer.
711 (*sender)->set_stream_id(local_stream->label());
700 } 712 }
701 } 713 }
702 714
703 stats_->AddStream(local_stream); 715 stats_->AddStream(local_stream);
704 observer_->OnRenegotiationNeeded(); 716 observer_->OnRenegotiationNeeded();
705 return true; 717 return true;
706 } 718 }
707 719
708 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around 720 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around
709 // indefinitely. 721 // indefinitely, when we have unified plan SDP.
710 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { 722 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
711 for (const auto& track : local_stream->GetAudioTracks()) { 723 for (const auto& track : local_stream->GetAudioTracks()) {
712 const TrackInfo* track_info = 724 auto sender = FindSenderForTrack(track.get());
713 FindTrackInfo(local_audio_tracks_, local_stream->label(), track->id()); 725 if (sender == senders_.end()) {
714 if (track_info) { 726 LOG(LS_WARNING) << "RtpSender for track with id " << track->id()
715 DestroyAudioSender(local_stream, track.get(), track_info->ssrc); 727 << " doesn't exist.";
728 continue;
716 } 729 }
730 (*sender)->Stop();
731 senders_.erase(sender);
717 } 732 }
718 for (const auto& track : local_stream->GetVideoTracks()) { 733 for (const auto& track : local_stream->GetVideoTracks()) {
719 const TrackInfo* track_info = 734 auto sender = FindSenderForTrack(track.get());
720 FindTrackInfo(local_video_tracks_, local_stream->label(), track->id()); 735 if (sender == senders_.end()) {
721 if (track_info) { 736 LOG(LS_WARNING) << "RtpSender for track with id " << track->id()
722 DestroyVideoSender(local_stream, track.get()); 737 << " doesn't exist.";
738 continue;
723 } 739 }
740 (*sender)->Stop();
741 senders_.erase(sender);
724 } 742 }
725 743
726 local_streams_->RemoveStream(local_stream); 744 local_streams_->RemoveStream(local_stream);
727 745
728 if (IsClosed()) { 746 if (IsClosed()) {
729 return; 747 return;
730 } 748 }
731 observer_->OnRenegotiationNeeded(); 749 observer_->OnRenegotiationNeeded();
732 } 750 }
733 751
(...skipping 10 matching lines...) Expand all
744 762
745 rtc::scoped_refptr<DtmfSenderInterface> sender( 763 rtc::scoped_refptr<DtmfSenderInterface> sender(
746 DtmfSender::Create(track, signaling_thread(), session_.get())); 764 DtmfSender::Create(track, signaling_thread(), session_.get()));
747 if (!sender.get()) { 765 if (!sender.get()) {
748 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; 766 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create.";
749 return NULL; 767 return NULL;
750 } 768 }
751 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); 769 return DtmfSenderProxy::Create(signaling_thread(), sender.get());
752 } 770 }
753 771
772 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
773 const std::string& kind) {
774 RtpSenderInterface* new_sender;
775 if (kind == MediaStreamTrackInterface::kAudioTrackKind) {
776 new_sender = new AudioRtpSender(session_.get(), stats_.get());
777 } else if (kind == MediaStreamTrackInterface::kVideoTrackKind) {
778 new_sender = new VideoRtpSender(session_.get());
779 } else {
780 LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
781 return rtc::scoped_refptr<RtpSenderInterface>();
782 }
783 senders_.push_back(new_sender);
784 return RtpSenderProxy::Create(signaling_thread(), new_sender);
785 }
786
754 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders() 787 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
755 const { 788 const {
756 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders; 789 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders;
757 for (const auto& sender : senders_) { 790 for (const auto& sender : senders_) {
758 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get())); 791 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get()));
759 } 792 }
760 return senders; 793 return senders;
761 } 794 }
762 795
763 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> 796 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 auto it = FindReceiverForTrack(video_track); 1293 auto it = FindReceiverForTrack(video_track);
1261 if (it == receivers_.end()) { 1294 if (it == receivers_.end()) {
1262 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() 1295 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id()
1263 << " doesn't exist."; 1296 << " doesn't exist.";
1264 } else { 1297 } else {
1265 (*it)->Stop(); 1298 (*it)->Stop();
1266 receivers_.erase(it); 1299 receivers_.erase(it);
1267 } 1300 }
1268 } 1301 }
1269 1302
1270 void PeerConnection::CreateAudioSender(MediaStreamInterface* stream,
1271 AudioTrackInterface* audio_track,
1272 uint32_t ssrc) {
1273 senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get()));
1274 stats_->AddLocalAudioTrack(audio_track, ssrc);
1275 }
1276
1277 void PeerConnection::CreateVideoSender(MediaStreamInterface* stream,
1278 VideoTrackInterface* video_track,
1279 uint32_t ssrc) {
1280 senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get()));
1281 }
1282
1283 // TODO(deadbeef): Keep RtpSenders around even if track goes away in local
1284 // description.
1285 void PeerConnection::DestroyAudioSender(MediaStreamInterface* stream,
1286 AudioTrackInterface* audio_track,
1287 uint32_t ssrc) {
1288 auto it = FindSenderForTrack(audio_track);
1289 if (it == senders_.end()) {
1290 LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id()
1291 << " doesn't exist.";
1292 return;
1293 } else {
1294 (*it)->Stop();
1295 senders_.erase(it);
1296 }
1297 stats_->RemoveLocalAudioTrack(audio_track, ssrc);
1298 }
1299
1300 void PeerConnection::DestroyVideoSender(MediaStreamInterface* stream,
1301 VideoTrackInterface* video_track) {
1302 auto it = FindSenderForTrack(video_track);
1303 if (it == senders_.end()) {
1304 LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id()
1305 << " doesn't exist.";
1306 return;
1307 } else {
1308 (*it)->Stop();
1309 senders_.erase(it);
1310 }
1311 }
1312
1313 void PeerConnection::OnIceConnectionChange( 1303 void PeerConnection::OnIceConnectionChange(
1314 PeerConnectionInterface::IceConnectionState new_state) { 1304 PeerConnectionInterface::IceConnectionState new_state) {
1315 RTC_DCHECK(signaling_thread()->IsCurrent()); 1305 RTC_DCHECK(signaling_thread()->IsCurrent());
1316 // After transitioning to "closed", ignore any additional states from 1306 // After transitioning to "closed", ignore any additional states from
1317 // WebRtcSession (such as "disconnected"). 1307 // WebRtcSession (such as "disconnected").
1318 if (IsClosed()) { 1308 if (IsClosed()) {
1319 return; 1309 return;
1320 } 1310 }
1321 ice_connection_state_ = new_state; 1311 ice_connection_state_ = new_state;
1322 observer_->OnIceConnectionChange(ice_connection_state_); 1312 observer_->OnIceConnectionChange(ice_connection_state_);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 signaling_thread()->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg); 1368 signaling_thread()->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
1379 } 1369 }
1380 1370
1381 bool PeerConnection::GetOptionsForOffer( 1371 bool PeerConnection::GetOptionsForOffer(
1382 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, 1372 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
1383 cricket::MediaSessionOptions* session_options) { 1373 cricket::MediaSessionOptions* session_options) {
1384 if (!ConvertRtcOptionsForOffer(rtc_options, session_options)) { 1374 if (!ConvertRtcOptionsForOffer(rtc_options, session_options)) {
1385 return false; 1375 return false;
1386 } 1376 }
1387 1377
1388 SetStreams(session_options, local_streams_, rtp_data_channels_); 1378 AddSendStreams(session_options, senders_, rtp_data_channels_);
1389 // Offer to receive audio/video if the constraint is not set and there are 1379 // Offer to receive audio/video if the constraint is not set and there are
1390 // send streams, or we're currently receiving. 1380 // send streams, or we're currently receiving.
1391 if (rtc_options.offer_to_receive_audio == RTCOfferAnswerOptions::kUndefined) { 1381 if (rtc_options.offer_to_receive_audio == RTCOfferAnswerOptions::kUndefined) {
1392 session_options->recv_audio = 1382 session_options->recv_audio =
1393 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO) || 1383 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO) ||
1394 !remote_audio_tracks_.empty(); 1384 !remote_audio_tracks_.empty();
1395 } 1385 }
1396 if (rtc_options.offer_to_receive_video == RTCOfferAnswerOptions::kUndefined) { 1386 if (rtc_options.offer_to_receive_video == RTCOfferAnswerOptions::kUndefined) {
1397 session_options->recv_video = 1387 session_options->recv_video =
1398 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO) || 1388 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO) ||
(...skipping 12 matching lines...) Expand all
1411 1401
1412 bool PeerConnection::GetOptionsForAnswer( 1402 bool PeerConnection::GetOptionsForAnswer(
1413 const MediaConstraintsInterface* constraints, 1403 const MediaConstraintsInterface* constraints,
1414 cricket::MediaSessionOptions* session_options) { 1404 cricket::MediaSessionOptions* session_options) {
1415 session_options->recv_audio = false; 1405 session_options->recv_audio = false;
1416 session_options->recv_video = false; 1406 session_options->recv_video = false;
1417 if (!ParseConstraintsForAnswer(constraints, session_options)) { 1407 if (!ParseConstraintsForAnswer(constraints, session_options)) {
1418 return false; 1408 return false;
1419 } 1409 }
1420 1410
1421 SetStreams(session_options, local_streams_, rtp_data_channels_); 1411 AddSendStreams(session_options, senders_, rtp_data_channels_);
1422 session_options->bundle_enabled = 1412 session_options->bundle_enabled =
1423 session_options->bundle_enabled && 1413 session_options->bundle_enabled &&
1424 (session_options->has_audio() || session_options->has_video() || 1414 (session_options->has_audio() || session_options->has_video() ||
1425 session_options->has_data()); 1415 session_options->has_data());
1426 1416
1427 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams 1417 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams
1428 // are not signaled in the SDP so does not go through that path and must be 1418 // are not signaled in the SDP so does not go through that path and must be
1429 // handled here. 1419 // handled here.
1430 if (session_->data_channel_type() == cricket::DCT_SCTP) { 1420 if (session_->data_channel_type() == cricket::DCT_SCTP) {
1431 session_options->data_channel_type = cricket::DCT_SCTP; 1421 session_options->data_channel_type = cricket::DCT_SCTP;
1432 } 1422 }
1433 return true; 1423 return true;
1434 } 1424 }
1435 1425
1436 void PeerConnection::UpdateRemoteStreamsList( 1426 void PeerConnection::UpdateRemoteStreamsList(
1437 const cricket::StreamParamsVec& streams, 1427 const cricket::StreamParamsVec& streams,
1438 cricket::MediaType media_type, 1428 cricket::MediaType media_type,
1439 StreamCollection* new_streams) { 1429 StreamCollection* new_streams) {
1440 TrackInfos* current_tracks = GetRemoteTracks(media_type); 1430 TrackInfos* current_tracks = GetRemoteTracks(media_type);
1441 1431
1442 // Find removed tracks. I.e., tracks where the track id or ssrc don't match 1432 // Find removed tracks. I.e., tracks where the track id or ssrc don't match
1443 // the 1433 // the new StreamParam.
1444 // new StreamParam.
1445 auto track_it = current_tracks->begin(); 1434 auto track_it = current_tracks->begin();
1446 while (track_it != current_tracks->end()) { 1435 while (track_it != current_tracks->end()) {
1447 const TrackInfo& info = *track_it; 1436 const TrackInfo& info = *track_it;
1448 const cricket::StreamParams* params = 1437 const cricket::StreamParams* params =
1449 cricket::GetStreamBySsrc(streams, info.ssrc); 1438 cricket::GetStreamBySsrc(streams, info.ssrc);
1450 if (!params || params->id != info.track_id) { 1439 if (!params || params->id != info.track_id) {
1451 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type); 1440 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type);
1452 track_it = current_tracks->erase(track_it); 1441 track_it = current_tracks->erase(track_it);
1453 } else { 1442 } else {
1454 ++track_it; 1443 ++track_it;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc)); 1625 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc));
1637 OnLocalTrackSeen(stream_label, track_id, params.first_ssrc(), media_type); 1626 OnLocalTrackSeen(stream_label, track_id, params.first_ssrc(), media_type);
1638 } 1627 }
1639 } 1628 }
1640 } 1629 }
1641 1630
1642 void PeerConnection::OnLocalTrackSeen(const std::string& stream_label, 1631 void PeerConnection::OnLocalTrackSeen(const std::string& stream_label,
1643 const std::string& track_id, 1632 const std::string& track_id,
1644 uint32_t ssrc, 1633 uint32_t ssrc,
1645 cricket::MediaType media_type) { 1634 cricket::MediaType media_type) {
1646 MediaStreamInterface* stream = local_streams_->find(stream_label); 1635 RtpSenderInterface* sender = FindSenderById(track_id);
1647 if (!stream) { 1636 if (!sender) {
1648 LOG(LS_WARNING) << "An unknown local MediaStream with label " 1637 LOG(LS_WARNING) << "An unknown RtpSender with id " << track_id
1649 << stream_label << " has been configured."; 1638 << " has been configured in the local description.";
1650 return; 1639 return;
1651 } 1640 }
1652 1641
1653 if (media_type == cricket::MEDIA_TYPE_AUDIO) { 1642 if (sender->media_type() != media_type) {
1654 AudioTrackInterface* audio_track = stream->FindAudioTrack(track_id); 1643 LOG(LS_WARNING) << "An RtpSender has been configured in the local"
1655 if (!audio_track) { 1644 << " description with an unexpected media type.";
1656 LOG(LS_WARNING) << "An unknown local AudioTrack with id , " << track_id 1645 return;
1657 << " has been configured.";
1658 return;
1659 }
1660 CreateAudioSender(stream, audio_track, ssrc);
1661 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1662 VideoTrackInterface* video_track = stream->FindVideoTrack(track_id);
1663 if (!video_track) {
1664 LOG(LS_WARNING) << "An unknown local VideoTrack with id , " << track_id
1665 << " has been configured.";
1666 return;
1667 }
1668 CreateVideoSender(stream, video_track, ssrc);
1669 } else {
1670 RTC_DCHECK(false && "Invalid media type");
1671 } 1646 }
1647
1648 sender->set_stream_id(stream_label);
1649 sender->SetSsrc(ssrc);
1672 } 1650 }
1673 1651
1674 void PeerConnection::OnLocalTrackRemoved(const std::string& stream_label, 1652 void PeerConnection::OnLocalTrackRemoved(const std::string& stream_label,
1675 const std::string& track_id, 1653 const std::string& track_id,
1676 uint32_t ssrc, 1654 uint32_t ssrc,
1677 cricket::MediaType media_type) { 1655 cricket::MediaType media_type) {
1678 MediaStreamInterface* stream = local_streams_->find(stream_label); 1656 RtpSenderInterface* sender = FindSenderById(track_id);
1679 if (!stream) { 1657 if (!sender) {
1680 // This is the normal case. I.e., RemoveLocalStream has been called and the 1658 // This is the normal case. I.e., RemoveStream has been called and the
1681 // SessionDescriptions has been renegotiated. 1659 // SessionDescriptions has been renegotiated.
1682 return; 1660 return;
1683 } 1661 }
1684 // A track has been removed from the SessionDescription but the MediaStream 1662
1685 // is still associated with PeerConnection. This only occurs if the SDP 1663 // A sender has been removed from the SessionDescription but it's still
1686 // doesn't match with the calls to AddLocalStream and RemoveLocalStream. 1664 // associated with the PeerConnection. This only occurs if the SDP doesn't
1687 if (media_type == cricket::MEDIA_TYPE_AUDIO) { 1665 // match with the calls to CreateSender, AddStream and RemoveStream.
1688 AudioTrackInterface* audio_track = stream->FindAudioTrack(track_id); 1666 if (sender->media_type() != media_type) {
1689 if (!audio_track) { 1667 LOG(LS_WARNING) << "An RtpSender has been configured in the local"
1690 return; 1668 << " description with an unexpected media type.";
1691 } 1669 return;
1692 DestroyAudioSender(stream, audio_track, ssrc);
1693 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1694 VideoTrackInterface* video_track = stream->FindVideoTrack(track_id);
1695 if (!video_track) {
1696 return;
1697 }
1698 DestroyVideoSender(stream, video_track);
1699 } else {
1700 RTC_DCHECK(false && "Invalid media type.");
1701 } 1670 }
1671
1672 sender->SetSsrc(0);
1702 } 1673 }
1703 1674
1704 void PeerConnection::UpdateLocalRtpDataChannels( 1675 void PeerConnection::UpdateLocalRtpDataChannels(
1705 const cricket::StreamParamsVec& streams) { 1676 const cricket::StreamParamsVec& streams) {
1706 std::vector<std::string> existing_channels; 1677 std::vector<std::string> existing_channels;
1707 1678
1708 // Find new and active data channels. 1679 // Find new and active data channels.
1709 for (const cricket::StreamParams& params : streams) { 1680 for (const cricket::StreamParams& params : streams) {
1710 // |it->sync_label| is actually the data channel label. The reason is that 1681 // |it->sync_label| is actually the data channel label. The reason is that
1711 // we use the same naming of data channels as we do for 1682 // we use the same naming of data channels as we do for
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1909 InternalCreateDataChannel(label, &config)); 1880 InternalCreateDataChannel(label, &config));
1910 if (!channel.get()) { 1881 if (!channel.get()) {
1911 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message."; 1882 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message.";
1912 return; 1883 return;
1913 } 1884 }
1914 1885
1915 observer_->OnDataChannel( 1886 observer_->OnDataChannel(
1916 DataChannelProxy::Create(signaling_thread(), channel)); 1887 DataChannelProxy::Create(signaling_thread(), channel));
1917 } 1888 }
1918 1889
1890 RtpSenderInterface* PeerConnection::FindSenderById(const std::string& id) {
1891 auto it =
1892 std::find_if(senders_.begin(), senders_.end(),
1893 [id](const rtc::scoped_refptr<RtpSenderInterface>& sender) {
1894 return sender->id() == id;
1895 });
1896 return it != senders_.end() ? it->get() : nullptr;
1897 }
1898
1919 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator 1899 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator
1920 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) { 1900 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) {
1921 return std::find_if( 1901 return std::find_if(
1922 senders_.begin(), senders_.end(), 1902 senders_.begin(), senders_.end(),
1923 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) { 1903 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) {
1924 return sender->track() == track; 1904 return sender->track() == track;
1925 }); 1905 });
1926 } 1906 }
1927 1907
1928 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator 1908 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1966 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { 1946 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const {
1967 for (const auto& channel : sctp_data_channels_) { 1947 for (const auto& channel : sctp_data_channels_) {
1968 if (channel->id() == sid) { 1948 if (channel->id() == sid) {
1969 return channel; 1949 return channel;
1970 } 1950 }
1971 } 1951 }
1972 return nullptr; 1952 return nullptr;
1973 } 1953 }
1974 1954
1975 } // namespace webrtc 1955 } // namespace webrtc
OLDNEW
« no previous file with comments | « talk/app/webrtc/peerconnection.h ('k') | talk/app/webrtc/peerconnection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698