| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 | 1080 |
| 1081 // If setting the description decided our SSL role, allocate any necessary | 1081 // If setting the description decided our SSL role, allocate any necessary |
| 1082 // SCTP sids. | 1082 // SCTP sids. |
| 1083 rtc::SSLRole role; | 1083 rtc::SSLRole role; |
| 1084 if (session_->data_channel_type() == cricket::DCT_SCTP && | 1084 if (session_->data_channel_type() == cricket::DCT_SCTP && |
| 1085 session_->GetSslRole(&role)) { | 1085 session_->GetSslRole(&role)) { |
| 1086 AllocateSctpSids(role); | 1086 AllocateSctpSids(role); |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 const cricket::SessionDescription* remote_desc = desc->description(); | 1089 const cricket::SessionDescription* remote_desc = desc->description(); |
| 1090 const cricket::ContentInfo* audio_content = GetFirstAudioContent(remote_desc); |
| 1091 const cricket::ContentInfo* video_content = GetFirstVideoContent(remote_desc); |
| 1092 const cricket::AudioContentDescription* audio_desc = |
| 1093 GetFirstAudioContentDescription(remote_desc); |
| 1094 const cricket::VideoContentDescription* video_desc = |
| 1095 GetFirstVideoContentDescription(remote_desc); |
| 1096 const cricket::DataContentDescription* data_desc = |
| 1097 GetFirstDataContentDescription(remote_desc); |
| 1098 |
| 1099 // Check if the descriptions include streams, just in case the peer supports |
| 1100 // MSID, but doesn't indicate so with "a=msid-semantic". |
| 1101 if (remote_desc->msid_supported() || |
| 1102 (audio_desc && !audio_desc->streams().empty()) || |
| 1103 (video_desc && !video_desc->streams().empty())) { |
| 1104 remote_peer_supports_msid_ = true; |
| 1105 } |
| 1090 | 1106 |
| 1091 // We wait to signal new streams until we finish processing the description, | 1107 // We wait to signal new streams until we finish processing the description, |
| 1092 // since only at that point will new streams have all their tracks. | 1108 // since only at that point will new streams have all their tracks. |
| 1093 rtc::scoped_refptr<StreamCollection> new_streams(StreamCollection::Create()); | 1109 rtc::scoped_refptr<StreamCollection> new_streams(StreamCollection::Create()); |
| 1094 | 1110 |
| 1095 // Find all audio rtp streams and create corresponding remote AudioTracks | 1111 // Find all audio rtp streams and create corresponding remote AudioTracks |
| 1096 // and MediaStreams. | 1112 // and MediaStreams. |
| 1097 const cricket::ContentInfo* audio_content = GetFirstAudioContent(remote_desc); | |
| 1098 if (audio_content) { | 1113 if (audio_content) { |
| 1099 if (audio_content->rejected) { | 1114 if (audio_content->rejected) { |
| 1100 RemoveTracks(cricket::MEDIA_TYPE_AUDIO); | 1115 RemoveTracks(cricket::MEDIA_TYPE_AUDIO); |
| 1101 } else { | 1116 } else { |
| 1102 const cricket::AudioContentDescription* desc = | 1117 bool default_audio_track_needed = |
| 1103 static_cast<const cricket::AudioContentDescription*>( | 1118 !remote_peer_supports_msid_ && |
| 1104 audio_content->description); | 1119 MediaContentDirectionHasSend(audio_desc->direction()); |
| 1105 UpdateRemoteStreamsList(GetActiveStreams(desc), desc->type(), | 1120 UpdateRemoteStreamsList(GetActiveStreams(audio_desc), |
| 1121 default_audio_track_needed, audio_desc->type(), |
| 1106 new_streams); | 1122 new_streams); |
| 1107 remote_info_.default_audio_track_needed = | |
| 1108 !remote_desc->msid_supported() && desc->streams().empty() && | |
| 1109 MediaContentDirectionHasSend(desc->direction()); | |
| 1110 } | 1123 } |
| 1111 } | 1124 } |
| 1112 | 1125 |
| 1113 // Find all video rtp streams and create corresponding remote VideoTracks | 1126 // Find all video rtp streams and create corresponding remote VideoTracks |
| 1114 // and MediaStreams. | 1127 // and MediaStreams. |
| 1115 const cricket::ContentInfo* video_content = GetFirstVideoContent(remote_desc); | |
| 1116 if (video_content) { | 1128 if (video_content) { |
| 1117 if (video_content->rejected) { | 1129 if (video_content->rejected) { |
| 1118 RemoveTracks(cricket::MEDIA_TYPE_VIDEO); | 1130 RemoveTracks(cricket::MEDIA_TYPE_VIDEO); |
| 1119 } else { | 1131 } else { |
| 1120 const cricket::VideoContentDescription* desc = | 1132 bool default_video_track_needed = |
| 1121 static_cast<const cricket::VideoContentDescription*>( | 1133 !remote_peer_supports_msid_ && |
| 1122 video_content->description); | 1134 MediaContentDirectionHasSend(video_desc->direction()); |
| 1123 UpdateRemoteStreamsList(GetActiveStreams(desc), desc->type(), | 1135 UpdateRemoteStreamsList(GetActiveStreams(video_desc), |
| 1136 default_video_track_needed, video_desc->type(), |
| 1124 new_streams); | 1137 new_streams); |
| 1125 remote_info_.default_video_track_needed = | |
| 1126 !remote_desc->msid_supported() && desc->streams().empty() && | |
| 1127 MediaContentDirectionHasSend(desc->direction()); | |
| 1128 } | 1138 } |
| 1129 } | 1139 } |
| 1130 | 1140 |
| 1131 // Update the DataChannels with the information from the remote peer. | 1141 // Update the DataChannels with the information from the remote peer. |
| 1132 const cricket::ContentInfo* data_content = GetFirstDataContent(remote_desc); | 1142 if (data_desc) { |
| 1133 if (data_content) { | 1143 if (rtc::starts_with(data_desc->protocol().data(), |
| 1134 const cricket::DataContentDescription* desc = | |
| 1135 static_cast<const cricket::DataContentDescription*>( | |
| 1136 data_content->description); | |
| 1137 if (rtc::starts_with(desc->protocol().data(), | |
| 1138 cricket::kMediaProtocolRtpPrefix)) { | 1144 cricket::kMediaProtocolRtpPrefix)) { |
| 1139 UpdateRemoteRtpDataChannels(GetActiveStreams(desc)); | 1145 UpdateRemoteRtpDataChannels(GetActiveStreams(data_desc)); |
| 1140 } | 1146 } |
| 1141 } | 1147 } |
| 1142 | 1148 |
| 1143 // Iterate new_streams and notify the observer about new MediaStreams. | 1149 // Iterate new_streams and notify the observer about new MediaStreams. |
| 1144 for (size_t i = 0; i < new_streams->count(); ++i) { | 1150 for (size_t i = 0; i < new_streams->count(); ++i) { |
| 1145 MediaStreamInterface* new_stream = new_streams->at(i); | 1151 MediaStreamInterface* new_stream = new_streams->at(i); |
| 1146 stats_->AddStream(new_stream); | 1152 stats_->AddStream(new_stream); |
| 1147 observer_->OnAddStream(new_stream); | 1153 observer_->OnAddStream(new_stream); |
| 1148 } | 1154 } |
| 1149 | 1155 |
| 1150 // Find removed MediaStreams. | 1156 UpdateEndedRemoteMediaStreams(); |
| 1151 if (remote_info_.IsDefaultMediaStreamNeeded() && | |
| 1152 remote_streams_->find(kDefaultStreamLabel) != nullptr) { | |
| 1153 // The default media stream already exists. No need to do anything. | |
| 1154 } else { | |
| 1155 UpdateEndedRemoteMediaStreams(); | |
| 1156 remote_info_.msid_supported |= remote_streams_->count() > 0; | |
| 1157 } | |
| 1158 MaybeCreateDefaultStream(); | |
| 1159 | 1157 |
| 1160 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); | 1158 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); |
| 1161 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); | 1159 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); |
| 1162 } | 1160 } |
| 1163 | 1161 |
| 1164 bool PeerConnection::SetConfiguration(const RTCConfiguration& config) { | 1162 bool PeerConnection::SetConfiguration(const RTCConfiguration& config) { |
| 1165 if (port_allocator_) { | 1163 if (port_allocator_) { |
| 1166 std::vector<PortAllocatorFactoryInterface::StunConfiguration> stuns; | 1164 std::vector<PortAllocatorFactoryInterface::StunConfiguration> stuns; |
| 1167 std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turns; | 1165 std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turns; |
| 1168 if (!ParseIceServers(config.servers, &stuns, &turns)) { | 1166 if (!ParseIceServers(config.servers, &stuns, &turns)) { |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1485 // are not signaled in the SDP so does not go through that path and must be | 1483 // are not signaled in the SDP so does not go through that path and must be |
| 1486 // handled here. | 1484 // handled here. |
| 1487 if (session_->data_channel_type() == cricket::DCT_SCTP) { | 1485 if (session_->data_channel_type() == cricket::DCT_SCTP) { |
| 1488 session_options->data_channel_type = cricket::DCT_SCTP; | 1486 session_options->data_channel_type = cricket::DCT_SCTP; |
| 1489 } | 1487 } |
| 1490 return true; | 1488 return true; |
| 1491 } | 1489 } |
| 1492 | 1490 |
| 1493 void PeerConnection::RemoveTracks(cricket::MediaType media_type) { | 1491 void PeerConnection::RemoveTracks(cricket::MediaType media_type) { |
| 1494 UpdateLocalTracks(std::vector<cricket::StreamParams>(), media_type); | 1492 UpdateLocalTracks(std::vector<cricket::StreamParams>(), media_type); |
| 1495 UpdateRemoteStreamsList(std::vector<cricket::StreamParams>(), media_type, | 1493 UpdateRemoteStreamsList(std::vector<cricket::StreamParams>(), false, |
| 1496 nullptr); | 1494 media_type, nullptr); |
| 1497 } | 1495 } |
| 1498 | 1496 |
| 1499 void PeerConnection::UpdateRemoteStreamsList( | 1497 void PeerConnection::UpdateRemoteStreamsList( |
| 1500 const cricket::StreamParamsVec& streams, | 1498 const cricket::StreamParamsVec& streams, |
| 1499 bool default_track_needed, |
| 1501 cricket::MediaType media_type, | 1500 cricket::MediaType media_type, |
| 1502 StreamCollection* new_streams) { | 1501 StreamCollection* new_streams) { |
| 1503 TrackInfos* current_tracks = GetRemoteTracks(media_type); | 1502 TrackInfos* current_tracks = GetRemoteTracks(media_type); |
| 1504 | 1503 |
| 1505 // Find removed tracks. I.e., tracks where the track id or ssrc don't match | 1504 // Find removed tracks. I.e., tracks where the track id or ssrc don't match |
| 1506 // the | 1505 // the new StreamParam. |
| 1507 // new StreamParam. | |
| 1508 auto track_it = current_tracks->begin(); | 1506 auto track_it = current_tracks->begin(); |
| 1509 while (track_it != current_tracks->end()) { | 1507 while (track_it != current_tracks->end()) { |
| 1510 const TrackInfo& info = *track_it; | 1508 const TrackInfo& info = *track_it; |
| 1511 const cricket::StreamParams* params = | 1509 const cricket::StreamParams* params = |
| 1512 cricket::GetStreamBySsrc(streams, info.ssrc); | 1510 cricket::GetStreamBySsrc(streams, info.ssrc); |
| 1513 if (!params || params->id != info.track_id) { | 1511 bool track_exists = params && params->id == info.track_id; |
| 1512 // If this is a default track, and we still need it, don't remove it. |
| 1513 if ((info.stream_label == kDefaultStreamLabel && default_track_needed) || |
| 1514 track_exists) { |
| 1515 ++track_it; |
| 1516 } else { |
| 1514 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type); | 1517 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type); |
| 1515 track_it = current_tracks->erase(track_it); | 1518 track_it = current_tracks->erase(track_it); |
| 1516 } else { | |
| 1517 ++track_it; | |
| 1518 } | 1519 } |
| 1519 } | 1520 } |
| 1520 | 1521 |
| 1521 // Find new and active tracks. | 1522 // Find new and active tracks. |
| 1522 for (const cricket::StreamParams& params : streams) { | 1523 for (const cricket::StreamParams& params : streams) { |
| 1523 // The sync_label is the MediaStream label and the |stream.id| is the | 1524 // The sync_label is the MediaStream label and the |stream.id| is the |
| 1524 // track id. | 1525 // track id. |
| 1525 const std::string& stream_label = params.sync_label; | 1526 const std::string& stream_label = params.sync_label; |
| 1526 const std::string& track_id = params.id; | 1527 const std::string& track_id = params.id; |
| 1527 uint32_t ssrc = params.first_ssrc(); | 1528 uint32_t ssrc = params.first_ssrc(); |
| 1528 | 1529 |
| 1529 rtc::scoped_refptr<MediaStreamInterface> stream = | 1530 rtc::scoped_refptr<MediaStreamInterface> stream = |
| 1530 remote_streams_->find(stream_label); | 1531 remote_streams_->find(stream_label); |
| 1531 if (!stream) { | 1532 if (!stream) { |
| 1532 // This is a new MediaStream. Create a new remote MediaStream. | 1533 // This is a new MediaStream. Create a new remote MediaStream. |
| 1533 stream = remote_stream_factory_->CreateMediaStream(stream_label); | 1534 stream = remote_stream_factory_->CreateMediaStream(stream_label); |
| 1534 remote_streams_->AddStream(stream); | 1535 remote_streams_->AddStream(stream); |
| 1535 new_streams->AddStream(stream); | 1536 new_streams->AddStream(stream); |
| 1536 } | 1537 } |
| 1537 | 1538 |
| 1538 const TrackInfo* track_info = | 1539 const TrackInfo* track_info = |
| 1539 FindTrackInfo(*current_tracks, stream_label, track_id); | 1540 FindTrackInfo(*current_tracks, stream_label, track_id); |
| 1540 if (!track_info) { | 1541 if (!track_info) { |
| 1541 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc)); | 1542 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc)); |
| 1542 OnRemoteTrackSeen(stream_label, track_id, ssrc, media_type); | 1543 OnRemoteTrackSeen(stream_label, track_id, ssrc, media_type); |
| 1543 } | 1544 } |
| 1544 } | 1545 } |
| 1546 |
| 1547 // Add default track if necessary. |
| 1548 if (default_track_needed) { |
| 1549 rtc::scoped_refptr<MediaStreamInterface> default_stream = |
| 1550 remote_streams_->find(kDefaultStreamLabel); |
| 1551 if (!default_stream) { |
| 1552 // Create the new default MediaStream. |
| 1553 default_stream = |
| 1554 remote_stream_factory_->CreateMediaStream(kDefaultStreamLabel); |
| 1555 remote_streams_->AddStream(default_stream); |
| 1556 new_streams->AddStream(default_stream); |
| 1557 } |
| 1558 std::string default_track_id = (media_type == cricket::MEDIA_TYPE_AUDIO) |
| 1559 ? kDefaultAudioTrackLabel |
| 1560 : kDefaultVideoTrackLabel; |
| 1561 const TrackInfo* default_track_info = |
| 1562 FindTrackInfo(*current_tracks, kDefaultStreamLabel, default_track_id); |
| 1563 if (!default_track_info) { |
| 1564 current_tracks->push_back( |
| 1565 TrackInfo(kDefaultStreamLabel, default_track_id, 0)); |
| 1566 OnRemoteTrackSeen(kDefaultStreamLabel, default_track_id, 0, media_type); |
| 1567 } |
| 1568 } |
| 1545 } | 1569 } |
| 1546 | 1570 |
| 1547 void PeerConnection::OnRemoteTrackSeen(const std::string& stream_label, | 1571 void PeerConnection::OnRemoteTrackSeen(const std::string& stream_label, |
| 1548 const std::string& track_id, | 1572 const std::string& track_id, |
| 1549 uint32_t ssrc, | 1573 uint32_t ssrc, |
| 1550 cricket::MediaType media_type) { | 1574 cricket::MediaType media_type) { |
| 1551 MediaStreamInterface* stream = remote_streams_->find(stream_label); | 1575 MediaStreamInterface* stream = remote_streams_->find(stream_label); |
| 1552 | 1576 |
| 1553 if (media_type == cricket::MEDIA_TYPE_AUDIO) { | 1577 if (media_type == cricket::MEDIA_TYPE_AUDIO) { |
| 1554 AudioTrackInterface* audio_track = | 1578 AudioTrackInterface* audio_track = |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 streams_to_remove.push_back(stream); | 1621 streams_to_remove.push_back(stream); |
| 1598 } | 1622 } |
| 1599 } | 1623 } |
| 1600 | 1624 |
| 1601 for (const auto& stream : streams_to_remove) { | 1625 for (const auto& stream : streams_to_remove) { |
| 1602 remote_streams_->RemoveStream(stream); | 1626 remote_streams_->RemoveStream(stream); |
| 1603 observer_->OnRemoveStream(stream); | 1627 observer_->OnRemoveStream(stream); |
| 1604 } | 1628 } |
| 1605 } | 1629 } |
| 1606 | 1630 |
| 1607 void PeerConnection::MaybeCreateDefaultStream() { | |
| 1608 if (!remote_info_.IsDefaultMediaStreamNeeded()) { | |
| 1609 return; | |
| 1610 } | |
| 1611 | |
| 1612 bool default_created = false; | |
| 1613 | |
| 1614 rtc::scoped_refptr<MediaStreamInterface> default_remote_stream = | |
| 1615 remote_streams_->find(kDefaultStreamLabel); | |
| 1616 if (default_remote_stream == nullptr) { | |
| 1617 default_created = true; | |
| 1618 default_remote_stream = | |
| 1619 remote_stream_factory_->CreateMediaStream(kDefaultStreamLabel); | |
| 1620 remote_streams_->AddStream(default_remote_stream); | |
| 1621 } | |
| 1622 if (remote_info_.default_audio_track_needed && | |
| 1623 default_remote_stream->GetAudioTracks().size() == 0) { | |
| 1624 remote_audio_tracks_.push_back( | |
| 1625 TrackInfo(kDefaultStreamLabel, kDefaultAudioTrackLabel, 0)); | |
| 1626 OnRemoteTrackSeen(kDefaultStreamLabel, kDefaultAudioTrackLabel, 0, | |
| 1627 cricket::MEDIA_TYPE_AUDIO); | |
| 1628 } | |
| 1629 if (remote_info_.default_video_track_needed && | |
| 1630 default_remote_stream->GetVideoTracks().size() == 0) { | |
| 1631 remote_video_tracks_.push_back( | |
| 1632 TrackInfo(kDefaultStreamLabel, kDefaultVideoTrackLabel, 0)); | |
| 1633 OnRemoteTrackSeen(kDefaultStreamLabel, kDefaultVideoTrackLabel, 0, | |
| 1634 cricket::MEDIA_TYPE_VIDEO); | |
| 1635 } | |
| 1636 if (default_created) { | |
| 1637 stats_->AddStream(default_remote_stream); | |
| 1638 observer_->OnAddStream(default_remote_stream); | |
| 1639 } | |
| 1640 } | |
| 1641 | |
| 1642 void PeerConnection::EndRemoteTracks(cricket::MediaType media_type) { | 1631 void PeerConnection::EndRemoteTracks(cricket::MediaType media_type) { |
| 1643 TrackInfos* current_tracks = GetRemoteTracks(media_type); | 1632 TrackInfos* current_tracks = GetRemoteTracks(media_type); |
| 1644 for (TrackInfos::iterator track_it = current_tracks->begin(); | 1633 for (TrackInfos::iterator track_it = current_tracks->begin(); |
| 1645 track_it != current_tracks->end(); ++track_it) { | 1634 track_it != current_tracks->end(); ++track_it) { |
| 1646 const TrackInfo& info = *track_it; | 1635 const TrackInfo& info = *track_it; |
| 1647 MediaStreamInterface* stream = remote_streams_->find(info.stream_label); | 1636 MediaStreamInterface* stream = remote_streams_->find(info.stream_label); |
| 1648 if (media_type == cricket::MEDIA_TYPE_AUDIO) { | 1637 if (media_type == cricket::MEDIA_TYPE_AUDIO) { |
| 1649 AudioTrackInterface* track = stream->FindAudioTrack(info.track_id); | 1638 AudioTrackInterface* track = stream->FindAudioTrack(info.track_id); |
| 1650 // There's no guarantee the track is still available, e.g. the track may | 1639 // There's no guarantee the track is still available, e.g. the track may |
| 1651 // have been removed from the stream by javascript. | 1640 // have been removed from the stream by javascript. |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2029 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { | 2018 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { |
| 2030 for (const auto& channel : sctp_data_channels_) { | 2019 for (const auto& channel : sctp_data_channels_) { |
| 2031 if (channel->id() == sid) { | 2020 if (channel->id() == sid) { |
| 2032 return channel; | 2021 return channel; |
| 2033 } | 2022 } |
| 2034 } | 2023 } |
| 2035 return nullptr; | 2024 return nullptr; |
| 2036 } | 2025 } |
| 2037 | 2026 |
| 2038 } // namespace webrtc | 2027 } // namespace webrtc |
| OLD | NEW |