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

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

Issue 1563403002: Adding AddTrack/RemoveTrack to native PeerConnection API. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Adding unit tests and fixing some issues. Created 4 years, 11 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 773 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 0; 784 0;
785 }), 785 }),
786 stream_observers_.end()); 786 stream_observers_.end());
787 787
788 if (IsClosed()) { 788 if (IsClosed()) {
789 return; 789 return;
790 } 790 }
791 observer_->OnRenegotiationNeeded(); 791 observer_->OnRenegotiationNeeded();
792 } 792 }
793 793
794 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::AddTrack(
795 MediaStreamTrackInterface* track,
796 std::vector<MediaStreamInterface*> streams) {
pthatcher1 2016/01/11 17:31:51 Would it make sense to only pass in a std::vector<
Taylor Brandstetter 2016/01/13 00:53:01 The reason for it to take a stream is that I want
797 TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
798 if (IsClosed()) {
799 return nullptr;
800 }
801 if (FindSenderForTrack(track) != senders_.end()) {
802 LOG(LS_ERROR) << "Sender for track " << track->id() << " already exists.";
803 return nullptr;
pthatcher1 2016/01/11 17:31:51 Will this be supported once we switch to Unified P
Taylor Brandstetter 2016/01/13 00:53:01 I guess I just assumed the spec didn't allow it. I
804 }
805
806 // TODO(deadbeef): Support adding a track to multiple streams.
807 rtc::scoped_refptr<RtpSenderInterface> new_sender;
808 if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
809 new_sender = RtpSenderProxy::Create(
810 signaling_thread(),
811 new AudioRtpSender(static_cast<AudioTrackInterface*>(track),
812 session_.get(), stats_.get()));
pthatcher1 2016/01/11 17:31:51 So later one when we want to do something with an
Taylor Brandstetter 2016/01/13 00:53:01 We would use the proxy object. If a method is call
813 if (!streams.empty()) {
814 new_sender->set_stream_id(streams[0]->label());
815 }
816 const TrackInfo* track_info = FindTrackInfo(
817 local_audio_tracks_, new_sender->stream_id(), track->id());
818 if (track_info) {
819 new_sender->SetSsrc(track_info->ssrc);
820 }
821 } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
822 new_sender = RtpSenderProxy::Create(
823 signaling_thread(),
824 new VideoRtpSender(static_cast<VideoTrackInterface*>(track),
825 session_.get()));
826 if (!streams.empty()) {
827 new_sender->set_stream_id(streams[0]->label());
828 }
829 const TrackInfo* track_info = FindTrackInfo(
830 local_video_tracks_, new_sender->stream_id(), track->id());
831 if (track_info) {
832 new_sender->SetSsrc(track_info->ssrc);
833 }
834 } else {
835 LOG(LS_ERROR) << "CreateSender called with invalid kind: " << track->kind();
836 return rtc::scoped_refptr<RtpSenderInterface>();
837 }
838
839 senders_.push_back(new_sender);
840 observer_->OnRenegotiationNeeded();
841 return new_sender;
842 }
843
844 bool PeerConnection::RemoveTrack(RtpSenderInterface* sender) {
845 TRACE_EVENT0("webrtc", "PeerConnection::RemoveTrack");
846
847 auto it = std::find(senders_.begin(), senders_.end(), sender);
848 if (it == senders_.end()) {
849 LOG(LS_ERROR) << "Couldn't find sender " << sender->id() << " to remove.";
850 return false;
851 }
852 senders_.erase(it);
853
854 if (!IsClosed()) {
855 observer_->OnRenegotiationNeeded();
856 }
pthatcher1 2016/01/11 17:31:51 We can RemoveTrack even if IsClosed()?
Taylor Brandstetter 2016/01/13 00:53:01 I was just matching RemoveStream, but it looks lik
857 return true;
858 }
859
794 rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender( 860 rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender(
795 AudioTrackInterface* track) { 861 AudioTrackInterface* track) {
796 TRACE_EVENT0("webrtc", "PeerConnection::CreateDtmfSender"); 862 TRACE_EVENT0("webrtc", "PeerConnection::CreateDtmfSender");
797 if (!track) { 863 if (!track) {
798 LOG(LS_ERROR) << "CreateDtmfSender - track is NULL."; 864 LOG(LS_ERROR) << "CreateDtmfSender - track is NULL.";
799 return NULL; 865 return NULL;
800 } 866 }
801 if (!local_streams_->FindAudioTrack(track->id())) { 867 if (!local_streams_->FindAudioTrack(track->id())) {
802 LOG(LS_ERROR) << "CreateDtmfSender is called with a non local audio track."; 868 LOG(LS_ERROR) << "CreateDtmfSender is called with a non local audio track.";
803 return NULL; 869 return NULL;
804 } 870 }
805 871
806 rtc::scoped_refptr<DtmfSenderInterface> sender( 872 rtc::scoped_refptr<DtmfSenderInterface> sender(
807 DtmfSender::Create(track, signaling_thread(), session_.get())); 873 DtmfSender::Create(track, signaling_thread(), session_.get()));
808 if (!sender.get()) { 874 if (!sender.get()) {
809 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create."; 875 LOG(LS_ERROR) << "CreateDtmfSender failed on DtmfSender::Create.";
810 return NULL; 876 return NULL;
811 } 877 }
812 return DtmfSenderProxy::Create(signaling_thread(), sender.get()); 878 return DtmfSenderProxy::Create(signaling_thread(), sender.get());
813 } 879 }
814 880
815 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender( 881 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
816 const std::string& kind, 882 const std::string& kind,
817 const std::string& stream_id) { 883 const std::string& stream_id) {
818 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender"); 884 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
819 RtpSenderInterface* new_sender; 885 rtc::scoped_refptr<RtpSenderInterface> new_sender;
820 if (kind == MediaStreamTrackInterface::kAudioKind) { 886 if (kind == MediaStreamTrackInterface::kAudioKind) {
821 new_sender = new AudioRtpSender(session_.get(), stats_.get()); 887 new_sender = RtpSenderProxy::Create(
888 signaling_thread(), new AudioRtpSender(session_.get(), stats_.get()));
822 } else if (kind == MediaStreamTrackInterface::kVideoKind) { 889 } else if (kind == MediaStreamTrackInterface::kVideoKind) {
823 new_sender = new VideoRtpSender(session_.get()); 890 new_sender = RtpSenderProxy::Create(signaling_thread(),
891 new VideoRtpSender(session_.get()));
824 } else { 892 } else {
825 LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind; 893 LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
826 return rtc::scoped_refptr<RtpSenderInterface>(); 894 return new_sender;
827 } 895 }
828 if (!stream_id.empty()) { 896 if (!stream_id.empty()) {
829 new_sender->set_stream_id(stream_id); 897 new_sender->set_stream_id(stream_id);
830 } 898 }
831 senders_.push_back(new_sender); 899 senders_.push_back(new_sender);
832 return RtpSenderProxy::Create(signaling_thread(), new_sender); 900 return new_sender;
833 } 901 }
834 902
835 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders() 903 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
836 const { 904 const {
837 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders; 905 return senders_;
838 for (const auto& sender : senders_) {
839 senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get()));
840 }
841 return senders;
842 } 906 }
843 907
844 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> 908 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
845 PeerConnection::GetReceivers() const { 909 PeerConnection::GetReceivers() const {
846 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers; 910 return receivers_;
847 for (const auto& receiver : receivers_) {
848 receivers.push_back(
849 RtpReceiverProxy::Create(signaling_thread(), receiver.get()));
850 }
851 return receivers;
852 } 911 }
853 912
854 bool PeerConnection::GetStats(StatsObserver* observer, 913 bool PeerConnection::GetStats(StatsObserver* observer,
855 MediaStreamTrackInterface* track, 914 MediaStreamTrackInterface* track,
856 StatsOutputLevel level) { 915 StatsOutputLevel level) {
857 TRACE_EVENT0("webrtc", "PeerConnection::GetStats"); 916 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
858 RTC_DCHECK(signaling_thread()->IsCurrent()); 917 RTC_DCHECK(signaling_thread()->IsCurrent());
859 if (!VERIFY(observer != NULL)) { 918 if (!VERIFY(observer != NULL)) {
860 LOG(LS_ERROR) << "GetStats - observer is NULL."; 919 LOG(LS_ERROR) << "GetStats - observer is NULL.";
861 return false; 920 return false;
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 } 1370 }
1312 default: 1371 default:
1313 RTC_DCHECK(false && "Not implemented"); 1372 RTC_DCHECK(false && "Not implemented");
1314 break; 1373 break;
1315 } 1374 }
1316 } 1375 }
1317 1376
1318 void PeerConnection::CreateAudioReceiver(MediaStreamInterface* stream, 1377 void PeerConnection::CreateAudioReceiver(MediaStreamInterface* stream,
1319 AudioTrackInterface* audio_track, 1378 AudioTrackInterface* audio_track,
1320 uint32_t ssrc) { 1379 uint32_t ssrc) {
1321 receivers_.push_back(new AudioRtpReceiver(audio_track, ssrc, session_.get())); 1380 receivers_.push_back(RtpReceiverProxy::Create(
1381 signaling_thread(),
1382 new AudioRtpReceiver(audio_track, ssrc, session_.get())));
1322 } 1383 }
1323 1384
1324 void PeerConnection::CreateVideoReceiver(MediaStreamInterface* stream, 1385 void PeerConnection::CreateVideoReceiver(MediaStreamInterface* stream,
1325 VideoTrackInterface* video_track, 1386 VideoTrackInterface* video_track,
1326 uint32_t ssrc) { 1387 uint32_t ssrc) {
1327 receivers_.push_back(new VideoRtpReceiver(video_track, ssrc, session_.get())); 1388 receivers_.push_back(RtpReceiverProxy::Create(
1389 signaling_thread(),
1390 new VideoRtpReceiver(video_track, ssrc, session_.get())));
1328 } 1391 }
1329 1392
1330 // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote 1393 // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote
1331 // description. 1394 // description.
1332 void PeerConnection::DestroyAudioReceiver(MediaStreamInterface* stream, 1395 void PeerConnection::DestroyAudioReceiver(MediaStreamInterface* stream,
1333 AudioTrackInterface* audio_track) { 1396 AudioTrackInterface* audio_track) {
1334 auto it = FindReceiverForTrack(audio_track); 1397 auto it = FindReceiverForTrack(audio_track);
1335 if (it == receivers_.end()) { 1398 if (it == receivers_.end()) {
1336 LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id() 1399 LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id()
1337 << " doesn't exist."; 1400 << " doesn't exist.";
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 MediaStreamInterface* stream) { 1472 MediaStreamInterface* stream) {
1410 auto sender = FindSenderForTrack(track); 1473 auto sender = FindSenderForTrack(track);
1411 if (sender != senders_.end()) { 1474 if (sender != senders_.end()) {
1412 // We already have a sender for this track, so just change the stream_id 1475 // We already have a sender for this track, so just change the stream_id
1413 // so that it's correct in the next call to CreateOffer. 1476 // so that it's correct in the next call to CreateOffer.
1414 (*sender)->set_stream_id(stream->label()); 1477 (*sender)->set_stream_id(stream->label());
1415 return; 1478 return;
1416 } 1479 }
1417 1480
1418 // Normal case; we've never seen this track before. 1481 // Normal case; we've never seen this track before.
1419 AudioRtpSender* new_sender = 1482 rtc::scoped_refptr<RtpSenderInterface> new_sender = RtpSenderProxy::Create(
1420 new AudioRtpSender(track, stream->label(), session_.get(), stats_.get()); 1483 signaling_thread(),
1484 new AudioRtpSender(track, stream->label(), session_.get(), stats_.get()));
1421 senders_.push_back(new_sender); 1485 senders_.push_back(new_sender);
1422 // If the sender has already been configured in SDP, we call SetSsrc, 1486 // If the sender has already been configured in SDP, we call SetSsrc,
1423 // which will connect the sender to the underlying transport. This can 1487 // which will connect the sender to the underlying transport. This can
1424 // occur if a local session description that contains the ID of the sender 1488 // occur if a local session description that contains the ID of the sender
1425 // is set before AddStream is called. It can also occur if the local 1489 // is set before AddStream is called. It can also occur if the local
1426 // session description is not changed and RemoveStream is called, and 1490 // session description is not changed and RemoveStream is called, and
1427 // later AddStream is called again with the same stream. 1491 // later AddStream is called again with the same stream.
1428 const TrackInfo* track_info = 1492 const TrackInfo* track_info =
1429 FindTrackInfo(local_audio_tracks_, stream->label(), track->id()); 1493 FindTrackInfo(local_audio_tracks_, stream->label(), track->id());
1430 if (track_info) { 1494 if (track_info) {
(...skipping 19 matching lines...) Expand all
1450 MediaStreamInterface* stream) { 1514 MediaStreamInterface* stream) {
1451 auto sender = FindSenderForTrack(track); 1515 auto sender = FindSenderForTrack(track);
1452 if (sender != senders_.end()) { 1516 if (sender != senders_.end()) {
1453 // We already have a sender for this track, so just change the stream_id 1517 // We already have a sender for this track, so just change the stream_id
1454 // so that it's correct in the next call to CreateOffer. 1518 // so that it's correct in the next call to CreateOffer.
1455 (*sender)->set_stream_id(stream->label()); 1519 (*sender)->set_stream_id(stream->label());
1456 return; 1520 return;
1457 } 1521 }
1458 1522
1459 // Normal case; we've never seen this track before. 1523 // Normal case; we've never seen this track before.
1460 VideoRtpSender* new_sender = 1524 rtc::scoped_refptr<RtpSenderInterface> new_sender = RtpSenderProxy::Create(
1461 new VideoRtpSender(track, stream->label(), session_.get()); 1525 signaling_thread(),
1526 new VideoRtpSender(track, stream->label(), session_.get()));
1462 senders_.push_back(new_sender); 1527 senders_.push_back(new_sender);
1463 const TrackInfo* track_info = 1528 const TrackInfo* track_info =
1464 FindTrackInfo(local_video_tracks_, stream->label(), track->id()); 1529 FindTrackInfo(local_video_tracks_, stream->label(), track->id());
1465 if (track_info) { 1530 if (track_info) {
1466 new_sender->SetSsrc(track_info->ssrc); 1531 new_sender->SetSsrc(track_info->ssrc);
1467 } 1532 }
1468 } 1533 }
1469 1534
1470 void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track, 1535 void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track,
1471 MediaStreamInterface* stream) { 1536 MediaStreamInterface* stream) {
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { 2141 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const {
2077 for (const auto& channel : sctp_data_channels_) { 2142 for (const auto& channel : sctp_data_channels_) {
2078 if (channel->id() == sid) { 2143 if (channel->id() == sid) {
2079 return channel; 2144 return channel;
2080 } 2145 }
2081 } 2146 }
2082 return nullptr; 2147 return nullptr;
2083 } 2148 }
2084 2149
2085 } // namespace webrtc 2150 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698