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 |