Chromium Code Reviews| 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); | |
|
pthatcher1
2015/12/03 20:07:39
I think you can use
const cricket::AudioContentD
Taylor Brandstetter
2015/12/04 22:04:54
I still need the ContentInfo pointers to tell if t
| |
| 1092 | |
| 1093 remote_peer_msid_supported_ |= remote_desc->msid_supported(); | |
| 1094 // Just in case the peer supports MSID, but doesn't indicate so with | |
| 1095 // "a=msid-semantic"... | |
| 1096 if (audio_content && | |
| 1097 !static_cast<const cricket::AudioContentDescription*>( | |
| 1098 audio_content->description) | |
| 1099 ->streams() | |
| 1100 .empty()) { | |
| 1101 remote_peer_msid_supported_ = true; | |
| 1102 } | |
| 1103 if (video_content && | |
| 1104 !static_cast<const cricket::VideoContentDescription*>( | |
| 1105 video_content->description) | |
| 1106 ->streams() | |
| 1107 .empty()) { | |
| 1108 remote_peer_msid_supported_ = true; | |
| 1109 } | |
|
pthatcher1
2015/12/03 20:07:40
I think it could be:
auto audio = GetFirstAudioCo
Taylor Brandstetter
2015/12/04 22:04:54
Done.
| |
| 1090 | 1110 |
| 1091 // We wait to signal new streams until we finish processing the description, | 1111 // 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. | 1112 // since only at that point will new streams have all their tracks. |
| 1093 rtc::scoped_refptr<StreamCollection> new_streams(StreamCollection::Create()); | 1113 rtc::scoped_refptr<StreamCollection> new_streams(StreamCollection::Create()); |
| 1094 | 1114 |
| 1095 // Find all audio rtp streams and create corresponding remote AudioTracks | 1115 // Find all audio rtp streams and create corresponding remote AudioTracks |
| 1096 // and MediaStreams. | 1116 // and MediaStreams. |
| 1097 const cricket::ContentInfo* audio_content = GetFirstAudioContent(remote_desc); | |
| 1098 if (audio_content) { | 1117 if (audio_content) { |
| 1099 if (audio_content->rejected) { | 1118 if (audio_content->rejected) { |
| 1100 RemoveTracks(cricket::MEDIA_TYPE_AUDIO); | 1119 RemoveTracks(cricket::MEDIA_TYPE_AUDIO); |
| 1101 } else { | 1120 } else { |
| 1102 const cricket::AudioContentDescription* desc = | 1121 const cricket::AudioContentDescription* desc = |
| 1103 static_cast<const cricket::AudioContentDescription*>( | 1122 static_cast<const cricket::AudioContentDescription*>( |
| 1104 audio_content->description); | 1123 audio_content->description); |
|
pthatcher1
2015/12/03 20:07:40
This line (or 3) could go away if you use the func
Taylor Brandstetter
2015/12/04 22:04:54
Done.
| |
| 1105 UpdateRemoteStreamsList(GetActiveStreams(desc), desc->type(), | 1124 bool default_audio_track_needed = |
| 1125 !remote_peer_msid_supported_ && desc->streams().empty() && | |
| 1126 MediaContentDirectionHasSend(desc->direction()); | |
| 1127 UpdateRemoteStreamsList(GetActiveStreams(desc), | |
| 1128 default_audio_track_needed, desc->type(), | |
| 1106 new_streams); | 1129 new_streams); |
| 1107 remote_info_.default_audio_track_needed = | |
| 1108 !remote_desc->msid_supported() && desc->streams().empty() && | |
| 1109 MediaContentDirectionHasSend(desc->direction()); | |
| 1110 } | 1130 } |
| 1111 } | 1131 } |
| 1112 | 1132 |
| 1113 // Find all video rtp streams and create corresponding remote VideoTracks | 1133 // Find all video rtp streams and create corresponding remote VideoTracks |
| 1114 // and MediaStreams. | 1134 // and MediaStreams. |
| 1115 const cricket::ContentInfo* video_content = GetFirstVideoContent(remote_desc); | |
| 1116 if (video_content) { | 1135 if (video_content) { |
| 1117 if (video_content->rejected) { | 1136 if (video_content->rejected) { |
| 1118 RemoveTracks(cricket::MEDIA_TYPE_VIDEO); | 1137 RemoveTracks(cricket::MEDIA_TYPE_VIDEO); |
| 1119 } else { | 1138 } else { |
| 1120 const cricket::VideoContentDescription* desc = | 1139 const cricket::VideoContentDescription* desc = |
| 1121 static_cast<const cricket::VideoContentDescription*>( | 1140 static_cast<const cricket::VideoContentDescription*>( |
| 1122 video_content->description); | 1141 video_content->description); |
| 1123 UpdateRemoteStreamsList(GetActiveStreams(desc), desc->type(), | 1142 bool default_video_track_needed = |
| 1143 !remote_peer_msid_supported_ && desc->streams().empty() && | |
| 1144 MediaContentDirectionHasSend(desc->direction()); | |
| 1145 UpdateRemoteStreamsList(GetActiveStreams(desc), | |
| 1146 default_video_track_needed, desc->type(), | |
| 1124 new_streams); | 1147 new_streams); |
| 1125 remote_info_.default_video_track_needed = | |
| 1126 !remote_desc->msid_supported() && desc->streams().empty() && | |
| 1127 MediaContentDirectionHasSend(desc->direction()); | |
| 1128 } | 1148 } |
| 1129 } | 1149 } |
| 1130 | 1150 |
| 1131 // Update the DataChannels with the information from the remote peer. | 1151 // Update the DataChannels with the information from the remote peer. |
| 1132 const cricket::ContentInfo* data_content = GetFirstDataContent(remote_desc); | 1152 const cricket::ContentInfo* data_content = GetFirstDataContent(remote_desc); |
| 1133 if (data_content) { | 1153 if (data_content) { |
| 1134 const cricket::DataContentDescription* desc = | 1154 const cricket::DataContentDescription* desc = |
| 1135 static_cast<const cricket::DataContentDescription*>( | 1155 static_cast<const cricket::DataContentDescription*>( |
| 1136 data_content->description); | 1156 data_content->description); |
| 1137 if (rtc::starts_with(desc->protocol().data(), | 1157 if (rtc::starts_with(desc->protocol().data(), |
| 1138 cricket::kMediaProtocolRtpPrefix)) { | 1158 cricket::kMediaProtocolRtpPrefix)) { |
| 1139 UpdateRemoteRtpDataChannels(GetActiveStreams(desc)); | 1159 UpdateRemoteRtpDataChannels(GetActiveStreams(desc)); |
| 1140 } | 1160 } |
| 1141 } | 1161 } |
| 1142 | 1162 |
| 1143 // Iterate new_streams and notify the observer about new MediaStreams. | 1163 // Iterate new_streams and notify the observer about new MediaStreams. |
| 1144 for (size_t i = 0; i < new_streams->count(); ++i) { | 1164 for (size_t i = 0; i < new_streams->count(); ++i) { |
| 1145 MediaStreamInterface* new_stream = new_streams->at(i); | 1165 MediaStreamInterface* new_stream = new_streams->at(i); |
| 1146 stats_->AddStream(new_stream); | 1166 stats_->AddStream(new_stream); |
| 1147 observer_->OnAddStream(new_stream); | 1167 observer_->OnAddStream(new_stream); |
| 1148 } | 1168 } |
| 1149 | 1169 |
| 1150 // Find removed MediaStreams. | 1170 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 | 1171 |
| 1160 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); | 1172 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); |
| 1161 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); | 1173 signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); |
| 1162 } | 1174 } |
| 1163 | 1175 |
| 1164 bool PeerConnection::SetConfiguration(const RTCConfiguration& config) { | 1176 bool PeerConnection::SetConfiguration(const RTCConfiguration& config) { |
| 1165 if (port_allocator_) { | 1177 if (port_allocator_) { |
| 1166 std::vector<PortAllocatorFactoryInterface::StunConfiguration> stuns; | 1178 std::vector<PortAllocatorFactoryInterface::StunConfiguration> stuns; |
| 1167 std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turns; | 1179 std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turns; |
| 1168 if (!ParseIceServers(config.servers, &stuns, &turns)) { | 1180 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 | 1497 // are not signaled in the SDP so does not go through that path and must be |
| 1486 // handled here. | 1498 // handled here. |
| 1487 if (session_->data_channel_type() == cricket::DCT_SCTP) { | 1499 if (session_->data_channel_type() == cricket::DCT_SCTP) { |
| 1488 session_options->data_channel_type = cricket::DCT_SCTP; | 1500 session_options->data_channel_type = cricket::DCT_SCTP; |
| 1489 } | 1501 } |
| 1490 return true; | 1502 return true; |
| 1491 } | 1503 } |
| 1492 | 1504 |
| 1493 void PeerConnection::RemoveTracks(cricket::MediaType media_type) { | 1505 void PeerConnection::RemoveTracks(cricket::MediaType media_type) { |
| 1494 UpdateLocalTracks(std::vector<cricket::StreamParams>(), media_type); | 1506 UpdateLocalTracks(std::vector<cricket::StreamParams>(), media_type); |
| 1495 UpdateRemoteStreamsList(std::vector<cricket::StreamParams>(), media_type, | 1507 UpdateRemoteStreamsList(std::vector<cricket::StreamParams>(), false, |
| 1496 nullptr); | 1508 media_type, nullptr); |
| 1497 } | 1509 } |
| 1498 | 1510 |
| 1499 void PeerConnection::UpdateRemoteStreamsList( | 1511 void PeerConnection::UpdateRemoteStreamsList( |
| 1500 const cricket::StreamParamsVec& streams, | 1512 const cricket::StreamParamsVec& streams, |
| 1513 bool default_track_needed, | |
| 1501 cricket::MediaType media_type, | 1514 cricket::MediaType media_type, |
| 1502 StreamCollection* new_streams) { | 1515 StreamCollection* new_streams) { |
| 1503 TrackInfos* current_tracks = GetRemoteTracks(media_type); | 1516 TrackInfos* current_tracks = GetRemoteTracks(media_type); |
| 1504 | 1517 |
| 1505 // Find removed tracks. I.e., tracks where the track id or ssrc don't match | 1518 // Find removed tracks. I.e., tracks where the track id or ssrc don't match |
| 1506 // the | 1519 // the new StreamParam. |
| 1507 // new StreamParam. | |
| 1508 auto track_it = current_tracks->begin(); | 1520 auto track_it = current_tracks->begin(); |
| 1509 while (track_it != current_tracks->end()) { | 1521 while (track_it != current_tracks->end()) { |
| 1510 const TrackInfo& info = *track_it; | 1522 const TrackInfo& info = *track_it; |
| 1511 const cricket::StreamParams* params = | 1523 const cricket::StreamParams* params = |
| 1512 cricket::GetStreamBySsrc(streams, info.ssrc); | 1524 cricket::GetStreamBySsrc(streams, info.ssrc); |
| 1513 if (!params || params->id != info.track_id) { | 1525 if (!params || params->id != info.track_id) { |
| 1526 // If this is a default track, and we still need it, don't remove it. | |
| 1527 if (info.stream_label == kDefaultStreamLabel && default_track_needed) { | |
| 1528 ++track_it; | |
| 1529 continue; | |
| 1530 } | |
| 1514 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type); | 1531 OnRemoteTrackRemoved(info.stream_label, info.track_id, media_type); |
| 1515 track_it = current_tracks->erase(track_it); | 1532 track_it = current_tracks->erase(track_it); |
| 1516 } else { | 1533 } else { |
| 1517 ++track_it; | 1534 ++track_it; |
| 1518 } | 1535 } |
|
pthatcher1
2015/12/03 20:07:40
Would it be more clear as this?
if (info.stream_l
Taylor Brandstetter
2015/12/04 22:04:54
I have another idea. Take a look.
pthatcher1
2015/12/05 00:31:41
I like it.
| |
| 1519 } | 1536 } |
| 1520 | 1537 |
| 1521 // Find new and active tracks. | 1538 // Find new and active tracks. |
| 1522 for (const cricket::StreamParams& params : streams) { | 1539 for (const cricket::StreamParams& params : streams) { |
| 1523 // The sync_label is the MediaStream label and the |stream.id| is the | 1540 // The sync_label is the MediaStream label and the |stream.id| is the |
| 1524 // track id. | 1541 // track id. |
| 1525 const std::string& stream_label = params.sync_label; | 1542 const std::string& stream_label = params.sync_label; |
| 1526 const std::string& track_id = params.id; | 1543 const std::string& track_id = params.id; |
| 1527 uint32_t ssrc = params.first_ssrc(); | 1544 uint32_t ssrc = params.first_ssrc(); |
| 1528 | 1545 |
| 1529 rtc::scoped_refptr<MediaStreamInterface> stream = | 1546 rtc::scoped_refptr<MediaStreamInterface> stream = |
| 1530 remote_streams_->find(stream_label); | 1547 remote_streams_->find(stream_label); |
| 1531 if (!stream) { | 1548 if (!stream) { |
| 1532 // This is a new MediaStream. Create a new remote MediaStream. | 1549 // This is a new MediaStream. Create a new remote MediaStream. |
| 1533 stream = remote_stream_factory_->CreateMediaStream(stream_label); | 1550 stream = remote_stream_factory_->CreateMediaStream(stream_label); |
| 1534 remote_streams_->AddStream(stream); | 1551 remote_streams_->AddStream(stream); |
| 1535 new_streams->AddStream(stream); | 1552 new_streams->AddStream(stream); |
| 1536 } | 1553 } |
| 1537 | 1554 |
| 1538 const TrackInfo* track_info = | 1555 const TrackInfo* track_info = |
| 1539 FindTrackInfo(*current_tracks, stream_label, track_id); | 1556 FindTrackInfo(*current_tracks, stream_label, track_id); |
| 1540 if (!track_info) { | 1557 if (!track_info) { |
| 1541 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc)); | 1558 current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc)); |
| 1542 OnRemoteTrackSeen(stream_label, track_id, ssrc, media_type); | 1559 OnRemoteTrackSeen(stream_label, track_id, ssrc, media_type); |
| 1543 } | 1560 } |
| 1544 } | 1561 } |
| 1562 | |
| 1563 // Add default track if necessary. | |
| 1564 if (default_track_needed) { | |
| 1565 rtc::scoped_refptr<MediaStreamInterface> stream = | |
| 1566 remote_streams_->find(kDefaultStreamLabel); | |
|
pthatcher1
2015/12/03 20:07:40
A better name for that variable might be "default_
Taylor Brandstetter
2015/12/04 22:04:54
Done.
| |
| 1567 if (!stream) { | |
| 1568 // Create the new default MediaStream. | |
| 1569 stream = remote_stream_factory_->CreateMediaStream(kDefaultStreamLabel); | |
| 1570 remote_streams_->AddStream(stream); | |
| 1571 new_streams->AddStream(stream); | |
| 1572 } | |
| 1573 std::string track_id = (media_type == cricket::MEDIA_TYPE_AUDIO) | |
| 1574 ? kDefaultAudioTrackLabel | |
| 1575 : kDefaultVideoTrackLabel; | |
|
pthatcher1
2015/12/03 20:07:40
And that default_track_id
Taylor Brandstetter
2015/12/04 22:04:54
Done.
| |
| 1576 const TrackInfo* track_info = | |
| 1577 FindTrackInfo(*current_tracks, kDefaultStreamLabel, track_id); | |
|
pthatcher1
2015/12/03 20:07:40
And that default_track
Taylor Brandstetter
2015/12/04 22:04:54
Done.
| |
| 1578 if (!track_info) { | |
| 1579 current_tracks->push_back(TrackInfo(kDefaultStreamLabel, track_id, 0)); | |
| 1580 OnRemoteTrackSeen(kDefaultStreamLabel, track_id, 0, media_type); | |
| 1581 } | |
| 1582 } | |
| 1545 } | 1583 } |
| 1546 | 1584 |
| 1547 void PeerConnection::OnRemoteTrackSeen(const std::string& stream_label, | 1585 void PeerConnection::OnRemoteTrackSeen(const std::string& stream_label, |
| 1548 const std::string& track_id, | 1586 const std::string& track_id, |
| 1549 uint32_t ssrc, | 1587 uint32_t ssrc, |
| 1550 cricket::MediaType media_type) { | 1588 cricket::MediaType media_type) { |
| 1551 MediaStreamInterface* stream = remote_streams_->find(stream_label); | 1589 MediaStreamInterface* stream = remote_streams_->find(stream_label); |
| 1552 | 1590 |
| 1553 if (media_type == cricket::MEDIA_TYPE_AUDIO) { | 1591 if (media_type == cricket::MEDIA_TYPE_AUDIO) { |
| 1554 AudioTrackInterface* audio_track = | 1592 AudioTrackInterface* audio_track = |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1597 streams_to_remove.push_back(stream); | 1635 streams_to_remove.push_back(stream); |
| 1598 } | 1636 } |
| 1599 } | 1637 } |
| 1600 | 1638 |
| 1601 for (const auto& stream : streams_to_remove) { | 1639 for (const auto& stream : streams_to_remove) { |
| 1602 remote_streams_->RemoveStream(stream); | 1640 remote_streams_->RemoveStream(stream); |
| 1603 observer_->OnRemoveStream(stream); | 1641 observer_->OnRemoveStream(stream); |
| 1604 } | 1642 } |
| 1605 } | 1643 } |
| 1606 | 1644 |
| 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) { | 1645 void PeerConnection::EndRemoteTracks(cricket::MediaType media_type) { |
| 1643 TrackInfos* current_tracks = GetRemoteTracks(media_type); | 1646 TrackInfos* current_tracks = GetRemoteTracks(media_type); |
| 1644 for (TrackInfos::iterator track_it = current_tracks->begin(); | 1647 for (TrackInfos::iterator track_it = current_tracks->begin(); |
| 1645 track_it != current_tracks->end(); ++track_it) { | 1648 track_it != current_tracks->end(); ++track_it) { |
| 1646 const TrackInfo& info = *track_it; | 1649 const TrackInfo& info = *track_it; |
| 1647 MediaStreamInterface* stream = remote_streams_->find(info.stream_label); | 1650 MediaStreamInterface* stream = remote_streams_->find(info.stream_label); |
| 1648 if (media_type == cricket::MEDIA_TYPE_AUDIO) { | 1651 if (media_type == cricket::MEDIA_TYPE_AUDIO) { |
| 1649 AudioTrackInterface* track = stream->FindAudioTrack(info.track_id); | 1652 AudioTrackInterface* track = stream->FindAudioTrack(info.track_id); |
| 1650 // There's no guarantee the track is still available, e.g. the track may | 1653 // There's no guarantee the track is still available, e.g. the track may |
| 1651 // have been removed from the stream by javascript. | 1654 // 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 { | 2032 DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { |
| 2030 for (const auto& channel : sctp_data_channels_) { | 2033 for (const auto& channel : sctp_data_channels_) { |
| 2031 if (channel->id() == sid) { | 2034 if (channel->id() == sid) { |
| 2032 return channel; | 2035 return channel; |
| 2033 } | 2036 } |
| 2034 } | 2037 } |
| 2035 return nullptr; | 2038 return nullptr; |
| 2036 } | 2039 } |
| 2037 | 2040 |
| 2038 } // namespace webrtc | 2041 } // namespace webrtc |
| OLD | NEW |