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

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

Issue 1413983004: Reland of Adding the ability to create an RtpSender without a track. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing merge issue. Created 5 years, 1 month 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 #include "webrtc/base/stringutils.h" 53 #include "webrtc/base/stringutils.h"
54 #include "webrtc/p2p/client/basicportallocator.h" 54 #include "webrtc/p2p/client/basicportallocator.h"
55 #include "webrtc/system_wrappers/include/field_trial.h" 55 #include "webrtc/system_wrappers/include/field_trial.h"
56 56
57 namespace { 57 namespace {
58 58
59 using webrtc::DataChannel; 59 using webrtc::DataChannel;
60 using webrtc::MediaConstraintsInterface; 60 using webrtc::MediaConstraintsInterface;
61 using webrtc::MediaStreamInterface; 61 using webrtc::MediaStreamInterface;
62 using webrtc::PeerConnectionInterface; 62 using webrtc::PeerConnectionInterface;
63 using webrtc::RtpSenderInterface;
63 using webrtc::StreamCollection; 64 using webrtc::StreamCollection;
64 using webrtc::StunConfigurations; 65 using webrtc::StunConfigurations;
65 using webrtc::TurnConfigurations; 66 using webrtc::TurnConfigurations;
66 typedef webrtc::PortAllocatorFactoryInterface::StunConfiguration 67 typedef webrtc::PortAllocatorFactoryInterface::StunConfiguration
67 StunConfiguration; 68 StunConfiguration;
68 typedef webrtc::PortAllocatorFactoryInterface::TurnConfiguration 69 typedef webrtc::PortAllocatorFactoryInterface::TurnConfiguration
69 TurnConfiguration; 70 TurnConfiguration;
70 71
71 static const char kDefaultStreamLabel[] = "default"; 72 static const char kDefaultStreamLabel[] = "default";
72 static const char kDefaultAudioTrackLabel[] = "defaulta0"; 73 static const char kDefaultAudioTrackLabel[] = "defaulta0";
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 : std::vector<cricket::StreamParams>(); 394 : std::vector<cricket::StreamParams>();
394 } 395 }
395 396
396 bool IsValidOfferToReceiveMedia(int value) { 397 bool IsValidOfferToReceiveMedia(int value) {
397 typedef PeerConnectionInterface::RTCOfferAnswerOptions Options; 398 typedef PeerConnectionInterface::RTCOfferAnswerOptions Options;
398 return (value >= Options::kUndefined) && 399 return (value >= Options::kUndefined) &&
399 (value <= Options::kMaxOfferToReceiveMedia); 400 (value <= Options::kMaxOfferToReceiveMedia);
400 } 401 }
401 402
402 // Add the stream and RTP data channel info to |session_options|. 403 // Add the stream and RTP data channel info to |session_options|.
403 void SetStreams(cricket::MediaSessionOptions* session_options, 404 void AddSendStreams(
404 rtc::scoped_refptr<StreamCollection> streams, 405 cricket::MediaSessionOptions* session_options,
405 const std::map<std::string, rtc::scoped_refptr<DataChannel>>& 406 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
406 rtp_data_channels) { 407 const std::map<std::string, rtc::scoped_refptr<DataChannel>>&
408 rtp_data_channels) {
407 session_options->streams.clear(); 409 session_options->streams.clear();
408 if (streams != nullptr) { 410 for (const auto& sender : senders) {
409 for (size_t i = 0; i < streams->count(); ++i) { 411 session_options->AddSendStream(sender->media_type(), sender->id(),
410 MediaStreamInterface* stream = streams->at(i); 412 sender->stream_id());
411 // For each audio track in the stream, add it to the MediaSessionOptions.
412 for (const auto& track : stream->GetAudioTracks()) {
413 session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, track->id(),
414 stream->label());
415 }
416 // For each video track in the stream, add it to the MediaSessionOptions.
417 for (const auto& track : stream->GetVideoTracks()) {
418 session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, track->id(),
419 stream->label());
420 }
421 }
422 } 413 }
423 414
424 // Check for data channels. 415 // Check for data channels.
425 for (const auto& kv : rtp_data_channels) { 416 for (const auto& kv : rtp_data_channels) {
426 const DataChannel* channel = kv.second; 417 const DataChannel* channel = kv.second;
427 if (channel->state() == DataChannel::kConnecting || 418 if (channel->state() == DataChannel::kConnecting ||
428 channel->state() == DataChannel::kOpen) { 419 channel->state() == DataChannel::kOpen) {
429 // |streamid| and |sync_label| are both set to the DataChannel label 420 // |streamid| and |sync_label| are both set to the DataChannel label
430 // here so they can be signaled the same way as MediaStreams and Tracks. 421 // here so they can be signaled the same way as MediaStreams and Tracks.
431 // For MediaStreams, the sync_label is the MediaStream label and the 422 // For MediaStreams, the sync_label is the MediaStream label and the
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 rtc::scoped_refptr<StreamCollectionInterface> 717 rtc::scoped_refptr<StreamCollectionInterface>
727 PeerConnection::local_streams() { 718 PeerConnection::local_streams() {
728 return local_streams_; 719 return local_streams_;
729 } 720 }
730 721
731 rtc::scoped_refptr<StreamCollectionInterface> 722 rtc::scoped_refptr<StreamCollectionInterface>
732 PeerConnection::remote_streams() { 723 PeerConnection::remote_streams() {
733 return remote_streams_; 724 return remote_streams_;
734 } 725 }
735 726
736 // TODO(deadbeef): Create RtpSenders immediately here, even if local
737 // description hasn't yet been set.
738 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) { 727 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
739 if (IsClosed()) { 728 if (IsClosed()) {
740 return false; 729 return false;
741 } 730 }
742 if (!CanAddLocalMediaStream(local_streams_, local_stream)) { 731 if (!CanAddLocalMediaStream(local_streams_, local_stream)) {
743 return false; 732 return false;
744 } 733 }
745 734
746 local_streams_->AddStream(local_stream); 735 local_streams_->AddStream(local_stream);
747 736
748 // Find tracks that have already been configured in SDP. This can occur if a
749 // local session description that contains the MSID of these tracks is set
750 // before AddLocalStream is called. It can also occur if the local session
751 // description is not changed and RemoveLocalStream is called and later
752 // AddLocalStream is called again with the same stream.
753 for (const auto& track : local_stream->GetAudioTracks()) { 737 for (const auto& track : local_stream->GetAudioTracks()) {
754 const TrackInfo* track_info = 738 auto sender = FindSenderForTrack(track.get());
755 FindTrackInfo(local_audio_tracks_, local_stream->label(), track->id()); 739 if (sender == senders_.end()) {
756 if (track_info) { 740 // Normal case; we've never seen this track before.
757 CreateAudioSender(local_stream, track.get(), track_info->ssrc); 741 AudioRtpSender* new_sender = new AudioRtpSender(
742 track.get(), local_stream->label(), session_.get(), stats_.get());
743 senders_.push_back(new_sender);
744 // If the sender has already been configured in SDP, we call SetSsrc,
745 // which will connect the sender to the underlying transport. This can
746 // occur if a local session description that contains the ID of the sender
747 // is set before AddStream is called. It can also occur if the local
748 // session description is not changed and RemoveStream is called, and
749 // later AddStream is called again with the same stream.
750 const TrackInfo* track_info = FindTrackInfo(
751 local_audio_tracks_, local_stream->label(), track->id());
752 if (track_info) {
753 new_sender->SetSsrc(track_info->ssrc);
754 }
755 } else {
756 // We already have a sender for this track, so just change the stream_id
757 // so that it's correct in the next call to CreateOffer.
758 (*sender)->set_stream_id(local_stream->label());
758 } 759 }
759 } 760 }
760 for (const auto& track : local_stream->GetVideoTracks()) { 761 for (const auto& track : local_stream->GetVideoTracks()) {
761 const TrackInfo* track_info = 762 auto sender = FindSenderForTrack(track.get());
762 FindTrackInfo(local_video_tracks_, local_stream->label(), track->id()); 763 if (sender == senders_.end()) {
763 if (track_info) { 764 // Normal case; we've never seen this track before.
764 CreateVideoSender(local_stream, track.get(), track_info->ssrc); 765 VideoRtpSender* new_sender = new VideoRtpSender(
766 track.get(), local_stream->label(), session_.get());
767 senders_.push_back(new_sender);
768 const TrackInfo* track_info = FindTrackInfo(
769 local_video_tracks_, local_stream->label(), track->id());
770 if (track_info) {
771 new_sender->SetSsrc(track_info->ssrc);
772 }
773 } else {
774 // We already have a sender for this track, so just change the stream_id
775 // so that it's correct in the next call to CreateOffer.
776 (*sender)->set_stream_id(local_stream->label());
765 } 777 }
766 } 778 }
767 779
768 stats_->AddStream(local_stream); 780 stats_->AddStream(local_stream);
769 observer_->OnRenegotiationNeeded(); 781 observer_->OnRenegotiationNeeded();
770 return true; 782 return true;
771 } 783 }
772 784
773 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around 785 // TODO(deadbeef): Don't destroy RtpSenders here; they should be kept around
774 // indefinitely. 786 // indefinitely, when we have unified plan SDP.
775 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) { 787 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
776 for (const auto& track : local_stream->GetAudioTracks()) { 788 for (const auto& track : local_stream->GetAudioTracks()) {
777 const TrackInfo* track_info = 789 auto sender = FindSenderForTrack(track.get());
778 FindTrackInfo(local_audio_tracks_, local_stream->label(), track->id()); 790 if (sender == senders_.end()) {
779 if (track_info) { 791 LOG(LS_WARNING) << "RtpSender for track with id " << track->id()
780 DestroyAudioSender(local_stream, track.get(), track_info->ssrc); 792 << " doesn't exist.";
793 continue;
781 } 794 }
795 (*sender)->Stop();
796 senders_.erase(sender);
782 } 797 }
783 for (const auto& track : local_stream->GetVideoTracks()) { 798 for (const auto& track : local_stream->GetVideoTracks()) {
784 const TrackInfo* track_info = 799 auto sender = FindSenderForTrack(track.get());
785 FindTrackInfo(local_video_tracks_, local_stream->label(), track->id()); 800 if (sender == senders_.end()) {
786 if (track_info) { 801 LOG(LS_WARNING) << "RtpSender for track with id " << track->id()
787 DestroyVideoSender(local_stream, track.get()); 802 << " doesn't exist.";
803 continue;
788 } 804 }
805 (*sender)->Stop();
806 senders_.erase(sender);
789 } 807 }
790 808
791 local_streams_->RemoveStream(local_stream); 809 local_streams_->RemoveStream(local_stream);
792 810
793 if (IsClosed()) { 811 if (IsClosed()) {
794 return; 812 return;
795 } 813 }
796 observer_->OnRenegotiationNeeded(); 814 observer_->OnRenegotiationNeeded();
797 } 815 }
798 816
(...skipping 10 matching lines...) Expand all
809 827
810 rtc::scoped_refptr<DtmfSenderInterface> sender( 828 rtc::scoped_refptr<DtmfSenderInterface> sender(
811 DtmfSender::Create(track, signaling_thread(), session_.get())); 829 DtmfSender::Create(track, signaling_thread(), session_.get()));
812 if (!sender.get()) { 830 if (!sender.get()) {
813 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; 831 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create.";
814 return NULL; 832 return NULL;
815 } 833 }
816 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); 834 return DtmfSenderProxy::Create(signaling_thread(), sender.get());
817 } 835 }
818 836
837 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
838 const std::string& kind) {
839 RtpSenderInterface* new_sender;
840 if (kind == MediaStreamTrackInterface::kAudioKind) {
841 new_sender = new AudioRtpSender(session_.get(), stats_.get());
842 } else if (kind == MediaStreamTrackInterface::kVideoKind) {
843 new_sender = new VideoRtpSender(session_.get());
844 } else {
845 LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
846 return rtc::scoped_refptr<RtpSenderInterface>();
847 }
848 senders_.push_back(new_sender);
849 return RtpSenderProxy::Create(signaling_thread(), new_sender);
850 }
851
819 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders() 852 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
820 const { 853 const {
821 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders; 854 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders;
822 for (const auto& sender : senders_) { 855 for (const auto& sender : senders_) {
823 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get())); 856 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get()));
824 } 857 }
825 return senders; 858 return senders;
826 } 859 }
827 860
828 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> 861 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 auto it = FindReceiverForTrack(video_track); 1350 auto it = FindReceiverForTrack(video_track);
1318 if (it == receivers_.end()) { 1351 if (it == receivers_.end()) {
1319 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() 1352 LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id()
1320 << " doesn't exist."; 1353 << " doesn't exist.";
1321 } else { 1354 } else {
1322 (*it)->Stop(); 1355 (*it)->Stop();
1323 receivers_.erase(it); 1356 receivers_.erase(it);
1324 } 1357 }
1325 } 1358 }
1326 1359
1327 void PeerConnection::CreateAudioSender(MediaStreamInterface* stream,
1328 AudioTrackInterface* audio_track,
1329 uint32_t ssrc) {
1330 senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get()));
1331 stats_->AddLocalAudioTrack(audio_track, ssrc);
1332 }
1333
1334 void PeerConnection::CreateVideoSender(MediaStreamInterface* stream,
1335 VideoTrackInterface* video_track,
1336 uint32_t ssrc) {
1337 senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get()));
1338 }
1339
1340 // TODO(deadbeef): Keep RtpSenders around even if track goes away in local
1341 // description.
1342 void PeerConnection::DestroyAudioSender(MediaStreamInterface* stream,
1343 AudioTrackInterface* audio_track,
1344 uint32_t ssrc) {
1345 auto it = FindSenderForTrack(audio_track);
1346 if (it == senders_.end()) {
1347 LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id()
1348 << " doesn't exist.";
1349 return;
1350 } else {
1351 (*it)->Stop();
1352 senders_.erase(it);
1353 }
1354 stats_->RemoveLocalAudioTrack(audio_track, ssrc);
1355 }
1356
1357 void PeerConnection::DestroyVideoSender(MediaStreamInterface* stream,
1358 VideoTrackInterface* video_track) {
1359 auto it = FindSenderForTrack(video_track);
1360 if (it == senders_.end()) {
1361 LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id()
1362 << " doesn't exist.";
1363 return;
1364 } else {
1365 (*it)->Stop();
1366 senders_.erase(it);
1367 }
1368 }
1369
1370 void PeerConnection::OnIceConnectionChange( 1360 void PeerConnection::OnIceConnectionChange(
1371 PeerConnectionInterface::IceConnectionState new_state) { 1361 PeerConnectionInterface::IceConnectionState new_state) {
1372 RTC_DCHECK(signaling_thread()->IsCurrent()); 1362 RTC_DCHECK(signaling_thread()->IsCurrent());
1373 // After transitioning to "closed", ignore any additional states from 1363 // After transitioning to "closed", ignore any additional states from
1374 // WebRtcSession (such as "disconnected"). 1364 // WebRtcSession (such as "disconnected").
1375 if (IsClosed()) { 1365 if (IsClosed()) {
1376 return; 1366 return;
1377 } 1367 }
1378 ice_connection_state_ = new_state; 1368 ice_connection_state_ = new_state;
1379 observer_->OnIceConnectionChange(ice_connection_state_); 1369 observer_->OnIceConnectionChange(ice_connection_state_);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 signaling_thread()->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg); 1425 signaling_thread()->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
1436 } 1426 }
1437 1427
1438 bool PeerConnection::GetOptionsForOffer( 1428 bool PeerConnection::GetOptionsForOffer(
1439 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, 1429 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
1440 cricket::MediaSessionOptions* session_options) { 1430 cricket::MediaSessionOptions* session_options) {
1441 if (!ConvertRtcOptionsForOffer(rtc_options, session_options)) { 1431 if (!ConvertRtcOptionsForOffer(rtc_options, session_options)) {
1442 return false; 1432 return false;
1443 } 1433 }
1444 1434
1445 SetStreams(session_options, local_streams_, rtp_data_channels_); 1435 AddSendStreams(session_options, senders_, rtp_data_channels_);
1446 // Offer to receive audio/video if the constraint is not set and there are 1436 // Offer to receive audio/video if the constraint is not set and there are
1447 // send streams, or we're currently receiving. 1437 // send streams, or we're currently receiving.
1448 if (rtc_options.offer_to_receive_audio == RTCOfferAnswerOptions::kUndefined) { 1438 if (rtc_options.offer_to_receive_audio == RTCOfferAnswerOptions::kUndefined) {
1449 session_options->recv_audio = 1439 session_options->recv_audio =
1450 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO) || 1440 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO) ||
1451 !remote_audio_tracks_.empty(); 1441 !remote_audio_tracks_.empty();
1452 } 1442 }
1453 if (rtc_options.offer_to_receive_video == RTCOfferAnswerOptions::kUndefined) { 1443 if (rtc_options.offer_to_receive_video == RTCOfferAnswerOptions::kUndefined) {
1454 session_options->recv_video = 1444 session_options->recv_video =
1455 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO) || 1445 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO) ||
(...skipping 12 matching lines...) Expand all
1468 1458
1469 bool PeerConnection::GetOptionsForAnswer( 1459 bool PeerConnection::GetOptionsForAnswer(
1470 const MediaConstraintsInterface* constraints, 1460 const MediaConstraintsInterface* constraints,
1471 cricket::MediaSessionOptions* session_options) { 1461 cricket::MediaSessionOptions* session_options) {
1472 session_options->recv_audio = false; 1462 session_options->recv_audio = false;
1473 session_options->recv_video = false; 1463 session_options->recv_video = false;
1474 if (!ParseConstraintsForAnswer(constraints, session_options)) { 1464 if (!ParseConstraintsForAnswer(constraints, session_options)) {
1475 return false; 1465 return false;
1476 } 1466 }
1477 1467
1478 SetStreams(session_options, local_streams_, rtp_data_channels_); 1468 AddSendStreams(session_options, senders_, rtp_data_channels_);
1479 session_options->bundle_enabled = 1469 session_options->bundle_enabled =
1480 session_options->bundle_enabled && 1470 session_options->bundle_enabled &&
1481 (session_options->has_audio() || session_options->has_video() || 1471 (session_options->has_audio() || session_options->has_video() ||
1482 session_options->has_data()); 1472 session_options->has_data());
1483 1473
1484 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams 1474 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams
1485 // are not signaled in the SDP so does not go through that path and must be 1475 // are not signaled in the SDP so does not go through that path and must be
1486 // handled here. 1476 // handled here.
1487 if (session_->data_channel_type() == cricket::DCT_SCTP) { 1477 if (session_->data_channel_type() == cricket::DCT_SCTP) {
1488 session_options->data_channel_type = cricket::DCT_SCTP; 1478 session_options->data_channel_type = cricket::DCT_SCTP;
1489 } 1479 }
1490 return true; 1480 return true;
1491 } 1481 }
1492 1482
1493 void PeerConnection::RemoveTracks(cricket::MediaType media_type) { 1483 void PeerConnection::RemoveTracks(cricket::MediaType media_type) {
1494 UpdateLocalTracks(std::vector<cricket::StreamParams>(), media_type); 1484 UpdateLocalTracks(std::vector<cricket::StreamParams>(), media_type);
1495 UpdateRemoteStreamsList(std::vector<cricket::StreamParams>(), media_type, 1485 UpdateRemoteStreamsList(std::vector<cricket::StreamParams>(), media_type,
1496 nullptr); 1486 nullptr);
1497 } 1487 }
1498 1488
1499 void PeerConnection::UpdateRemoteStreamsList( 1489 void PeerConnection::UpdateRemoteStreamsList(
1500 const cricket::StreamParamsVec& streams, 1490 const cricket::StreamParamsVec& streams,
1501 cricket::MediaType media_type, 1491 cricket::MediaType media_type,
1502 StreamCollection* new_streams) { 1492 StreamCollection* new_streams) {
1503 TrackInfos* current_tracks = GetRemoteTracks(media_type); 1493 TrackInfos* current_tracks = GetRemoteTracks(media_type);
1504 1494
1505 // Find removed tracks. I.e., tracks where the track id or ssrc don't match 1495 // Find removed tracks. I.e., tracks where the track id or ssrc don't match
1506 // the 1496 // the new StreamParam.
1507 // new StreamParam.
1508 auto track_it = current_tracks->begin(); 1497 auto track_it = current_tracks->begin();
1509 while (track_it != current_tracks->end()) { 1498 while (track_it != current_tracks->end()) {
1510 const TrackInfo& info = *track_it; 1499 const TrackInfo& info = *track_it;
1511 const cricket::StreamParams* params = 1500 const cricket::StreamParams* params =
1512 cricket::GetStreamBySsrc(streams, info.ssrc); 1501 cricket::GetStreamBySsrc(streams, info.ssrc);
1513 if (!params || params->id != info.track_id) { 1502 if (!params || params->id != info.track_id) {
1514 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type); 1503 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type);
1515 track_it = current_tracks->erase(track_it); 1504 track_it = current_tracks->erase(track_it);
1516 } else { 1505 } else {
1517 ++track_it; 1506 ++track_it;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc)); 1688 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc));
1700 OnLocalTrackSeen(stream_label, track_id, params.first_ssrc(), media_type); 1689 OnLocalTrackSeen(stream_label, track_id, params.first_ssrc(), media_type);
1701 } 1690 }
1702 } 1691 }
1703 } 1692 }
1704 1693
1705 void PeerConnection::OnLocalTrackSeen(const std::string& stream_label, 1694 void PeerConnection::OnLocalTrackSeen(const std::string& stream_label,
1706 const std::string& track_id, 1695 const std::string& track_id,
1707 uint32_t ssrc, 1696 uint32_t ssrc,
1708 cricket::MediaType media_type) { 1697 cricket::MediaType media_type) {
1709 MediaStreamInterface* stream = local_streams_->find(stream_label); 1698 RtpSenderInterface* sender = FindSenderById(track_id);
1710 if (!stream) { 1699 if (!sender) {
1711 LOG(LS_WARNING) << "An unknown local MediaStream with label " 1700 LOG(LS_WARNING) << "An unknown RtpSender with id " << track_id
1712 << stream_label << " has been configured."; 1701 << " has been configured in the local description.";
1713 return; 1702 return;
1714 } 1703 }
1715 1704
1716 if (media_type == cricket::MEDIA_TYPE_AUDIO) { 1705 if (sender->media_type() != media_type) {
1717 AudioTrackInterface* audio_track = stream->FindAudioTrack(track_id); 1706 LOG(LS_WARNING) << "An RtpSender has been configured in the local"
1718 if (!audio_track) { 1707 << " description with an unexpected media type.";
1719 LOG(LS_WARNING) << "An unknown local AudioTrack with id , " << track_id 1708 return;
1720 << " has been configured.";
1721 return;
1722 }
1723 CreateAudioSender(stream, audio_track, ssrc);
1724 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1725 VideoTrackInterface* video_track = stream->FindVideoTrack(track_id);
1726 if (!video_track) {
1727 LOG(LS_WARNING) << "An unknown local VideoTrack with id , " << track_id
1728 << " has been configured.";
1729 return;
1730 }
1731 CreateVideoSender(stream, video_track, ssrc);
1732 } else {
1733 RTC_DCHECK(false && "Invalid media type");
1734 } 1709 }
1710
1711 sender->set_stream_id(stream_label);
1712 sender->SetSsrc(ssrc);
1735 } 1713 }
1736 1714
1737 void PeerConnection::OnLocalTrackRemoved(const std::string& stream_label, 1715 void PeerConnection::OnLocalTrackRemoved(const std::string& stream_label,
1738 const std::string& track_id, 1716 const std::string& track_id,
1739 uint32_t ssrc, 1717 uint32_t ssrc,
1740 cricket::MediaType media_type) { 1718 cricket::MediaType media_type) {
1741 MediaStreamInterface* stream = local_streams_->find(stream_label); 1719 RtpSenderInterface* sender = FindSenderById(track_id);
1742 if (!stream) { 1720 if (!sender) {
1743 // This is the normal case. I.e., RemoveLocalStream has been called and the 1721 // This is the normal case. I.e., RemoveStream has been called and the
1744 // SessionDescriptions has been renegotiated. 1722 // SessionDescriptions has been renegotiated.
1745 return; 1723 return;
1746 } 1724 }
1747 // A track has been removed from the SessionDescription but the MediaStream 1725
1748 // is still associated with PeerConnection. This only occurs if the SDP 1726 // A sender has been removed from the SessionDescription but it's still
1749 // doesn't match with the calls to AddLocalStream and RemoveLocalStream. 1727 // associated with the PeerConnection. This only occurs if the SDP doesn't
1750 if (media_type == cricket::MEDIA_TYPE_AUDIO) { 1728 // match with the calls to CreateSender, AddStream and RemoveStream.
1751 AudioTrackInterface* audio_track = stream->FindAudioTrack(track_id); 1729 if (sender->media_type() != media_type) {
1752 if (!audio_track) { 1730 LOG(LS_WARNING) << "An RtpSender has been configured in the local"
1753 return; 1731 << " description with an unexpected media type.";
1754 } 1732 return;
1755 DestroyAudioSender(stream, audio_track, ssrc);
1756 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1757 VideoTrackInterface* video_track = stream->FindVideoTrack(track_id);
1758 if (!video_track) {
1759 return;
1760 }
1761 DestroyVideoSender(stream, video_track);
1762 } else {
1763 RTC_DCHECK(false && "Invalid media type.");
1764 } 1733 }
1734
1735 sender->SetSsrc(0);
1765 } 1736 }
1766 1737
1767 void PeerConnection::UpdateLocalRtpDataChannels( 1738 void PeerConnection::UpdateLocalRtpDataChannels(
1768 const cricket::StreamParamsVec& streams) { 1739 const cricket::StreamParamsVec& streams) {
1769 std::vector<std::string> existing_channels; 1740 std::vector<std::string> existing_channels;
1770 1741
1771 // Find new and active data channels. 1742 // Find new and active data channels.
1772 for (const cricket::StreamParams& params : streams) { 1743 for (const cricket::StreamParams& params : streams) {
1773 // |it->sync_label| is actually the data channel label. The reason is that 1744 // |it->sync_label| is actually the data channel label. The reason is that
1774 // we use the same naming of data channels as we do for 1745 // we use the same naming of data channels as we do for
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 InternalCreateDataChannel(label, &config)); 1943 InternalCreateDataChannel(label, &config));
1973 if (!channel.get()) { 1944 if (!channel.get()) {
1974 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message."; 1945 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message.";
1975 return; 1946 return;
1976 } 1947 }
1977 1948
1978 observer_->OnDataChannel( 1949 observer_->OnDataChannel(
1979 DataChannelProxy::Create(signaling_thread(), channel)); 1950 DataChannelProxy::Create(signaling_thread(), channel));
1980 } 1951 }
1981 1952
1953 RtpSenderInterface* PeerConnection::FindSenderById(const std::string& id) {
1954 auto it =
1955 std::find_if(senders_.begin(), senders_.end(),
1956 [id](const rtc::scoped_refptr<RtpSenderInterface>& sender) {
1957 return sender->id() == id;
1958 });
1959 return it != senders_.end() ? it->get() : nullptr;
1960 }
1961
1982 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator 1962 std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator
1983 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) { 1963 PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) {
1984 return std::find_if( 1964 return std::find_if(
1985 senders_.begin(), senders_.end(), 1965 senders_.begin(), senders_.end(),
1986 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) { 1966 [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) {
1987 return sender->track() == track; 1967 return sender->track() == track;
1988 }); 1968 });
1989 } 1969 }
1990 1970
1991 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator 1971 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2029 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { 2009 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const {
2030 for (const auto& channel : sctp_data_channels_) { 2010 for (const auto& channel : sctp_data_channels_) {
2031 if (channel->id() == sid) { 2011 if (channel->id() == sid) {
2032 return channel; 2012 return channel;
2033 } 2013 }
2034 } 2014 }
2035 return nullptr; 2015 return nullptr;
2036 } 2016 }
2037 2017
2038 } // namespace webrtc 2018 } // 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