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

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: Adding some unit tests for new methods on the sender. 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
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 // 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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698