Factor out the transceiver list into a separate object.
This component is heavily referenced by both PeerConnection and SdpOfferAnswerHandler; it's likely that it will end up in SdpOfferAnswerHandler. Encapsulation makes it easier to move around. Bug: webrtc:11995 Change-Id: I5329d9a90159d203510bf3698962cd246eea7324 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/185880 Commit-Queue: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32229}
This commit is contained in:
parent
b6bc09b099
commit
38b768c588
@ -217,6 +217,8 @@ rtc_library("peerconnection") {
|
||||
"stream_collection.h",
|
||||
"track_media_info_map.cc",
|
||||
"track_media_info_map.h",
|
||||
"transceiver_list.cc",
|
||||
"transceiver_list.h",
|
||||
"video_rtp_receiver.cc",
|
||||
"video_rtp_receiver.h",
|
||||
"video_rtp_track_source.cc",
|
||||
|
||||
@ -435,28 +435,6 @@ bool PeerConnectionInterface::RTCConfiguration::operator!=(
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
void PeerConnection::TransceiverStableState::set_newly_created() {
|
||||
RTC_DCHECK(!has_m_section_);
|
||||
newly_created_ = true;
|
||||
}
|
||||
|
||||
void PeerConnection::TransceiverStableState::SetMSectionIfUnset(
|
||||
absl::optional<std::string> mid,
|
||||
absl::optional<size_t> mline_index) {
|
||||
if (!has_m_section_) {
|
||||
mid_ = mid;
|
||||
mline_index_ = mline_index;
|
||||
has_m_section_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PeerConnection::TransceiverStableState::SetRemoteStreamIdsIfUnset(
|
||||
const std::vector<std::string>& ids) {
|
||||
if (!remote_stream_ids_.has_value()) {
|
||||
remote_stream_ids_ = ids;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a RTCP CNAME when a PeerConnection is created.
|
||||
std::string GenerateRtcpCname() {
|
||||
std::string cname;
|
||||
@ -501,7 +479,7 @@ PeerConnection::~PeerConnection() {
|
||||
// Need to stop transceivers before destroying the stats collector because
|
||||
// AudioRtpSender has a reference to the StatsCollector it will update when
|
||||
// stopping.
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
transceiver->StopInternal();
|
||||
}
|
||||
|
||||
@ -555,12 +533,12 @@ PeerConnection::~PeerConnection() {
|
||||
void PeerConnection::DestroyAllChannels() {
|
||||
// Destroy video channels first since they may have a pointer to a voice
|
||||
// channel.
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
if (transceiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
|
||||
DestroyTransceiverChannel(transceiver);
|
||||
}
|
||||
}
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
|
||||
DestroyTransceiverChannel(transceiver);
|
||||
}
|
||||
@ -780,12 +758,10 @@ bool PeerConnection::Initialize(
|
||||
|
||||
// Add default audio/video transceivers for Plan B SDP.
|
||||
if (!IsUnifiedPlan()) {
|
||||
transceivers_.push_back(
|
||||
RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
|
||||
signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_AUDIO)));
|
||||
transceivers_.push_back(
|
||||
RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
|
||||
signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_VIDEO)));
|
||||
transceivers_.Add(RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
|
||||
signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_AUDIO)));
|
||||
transceivers_.Add(RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
|
||||
signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_VIDEO)));
|
||||
}
|
||||
int delay_ms =
|
||||
return_histogram_very_quickly_ ? 0 : REPORT_USAGE_PATTERN_DELAY_MS;
|
||||
@ -1014,7 +990,7 @@ rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
PeerConnection::FindFirstTransceiverForAddedTrack(
|
||||
rtc::scoped_refptr<MediaStreamTrackInterface> track) {
|
||||
RTC_DCHECK(track);
|
||||
for (auto transceiver : transceivers_) {
|
||||
for (auto transceiver : transceivers_.List()) {
|
||||
if (!transceiver->sender()->track() &&
|
||||
cricket::MediaTypeToString(transceiver->media_type()) ==
|
||||
track->kind() &&
|
||||
@ -1075,12 +1051,7 @@ RTCError PeerConnection::RemoveTrackNew(
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
PeerConnection::FindTransceiverBySender(
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender) {
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->sender() == sender) {
|
||||
return transceiver;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return transceivers_.FindBySender(sender);
|
||||
}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
|
||||
@ -1300,7 +1271,7 @@ PeerConnection::CreateAndAddTransceiver(
|
||||
sender->media_type() == cricket::MEDIA_TYPE_AUDIO
|
||||
? channel_manager()->GetSupportedAudioRtpHeaderExtensions()
|
||||
: channel_manager()->GetSupportedVideoRtpHeaderExtensions()));
|
||||
transceivers_.push_back(transceiver);
|
||||
transceivers_.Add(transceiver);
|
||||
transceiver->internal()->SignalNegotiationNeeded.connect(
|
||||
this, &PeerConnection::OnNegotiationNeeded);
|
||||
return transceiver;
|
||||
@ -1375,7 +1346,7 @@ std::vector<rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>>>
|
||||
PeerConnection::GetSendersInternal() const {
|
||||
std::vector<rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>>>
|
||||
all_senders;
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
if (IsUnifiedPlan() && transceiver->internal()->stopped())
|
||||
continue;
|
||||
|
||||
@ -1401,7 +1372,7 @@ PeerConnection::GetReceiversInternal() const {
|
||||
std::vector<
|
||||
rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>>
|
||||
all_receivers;
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
if (IsUnifiedPlan() && transceiver->internal()->stopped())
|
||||
continue;
|
||||
|
||||
@ -1418,7 +1389,7 @@ PeerConnection::GetTransceivers() const {
|
||||
RTC_CHECK(IsUnifiedPlan())
|
||||
<< "GetTransceivers is only supported with Unified Plan SdpSemantics.";
|
||||
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
all_transceivers.push_back(transceiver);
|
||||
}
|
||||
return all_transceivers;
|
||||
@ -1464,7 +1435,7 @@ void PeerConnection::GetStats(
|
||||
RTC_DCHECK(stats_collector_);
|
||||
rtc::scoped_refptr<RtpSenderInternal> internal_sender;
|
||||
if (selector) {
|
||||
for (const auto& proxy_transceiver : transceivers_) {
|
||||
for (const auto& proxy_transceiver : transceivers_.List()) {
|
||||
for (const auto& proxy_sender :
|
||||
proxy_transceiver->internal()->senders()) {
|
||||
if (proxy_sender == selector) {
|
||||
@ -1493,7 +1464,7 @@ void PeerConnection::GetStats(
|
||||
RTC_DCHECK(stats_collector_);
|
||||
rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
|
||||
if (selector) {
|
||||
for (const auto& proxy_transceiver : transceivers_) {
|
||||
for (const auto& proxy_transceiver : transceivers_.List()) {
|
||||
for (const auto& proxy_receiver :
|
||||
proxy_transceiver->internal()->receivers()) {
|
||||
if (proxy_receiver == selector) {
|
||||
@ -1670,7 +1641,7 @@ PeerConnection::GetReceivingTransceiversOfType(cricket::MediaType media_type) {
|
||||
std::vector<
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
|
||||
receiving_transceivers;
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
if (!transceiver->stopped() && transceiver->media_type() == media_type &&
|
||||
RtpTransceiverDirectionHasRecv(transceiver->direction())) {
|
||||
receiving_transceivers.push_back(transceiver);
|
||||
@ -1711,15 +1682,15 @@ void PeerConnection::RemoveStoppedTransceivers() {
|
||||
// run the following steps:
|
||||
if (!IsUnifiedPlan())
|
||||
return;
|
||||
for (auto it = transceivers_.begin(); it != transceivers_.end();) {
|
||||
const auto& transceiver = *it;
|
||||
// Traverse a copy of the transceiver list.
|
||||
auto transceiver_list = transceivers_.List();
|
||||
for (auto transceiver : transceiver_list) {
|
||||
// 3.2.10.1.1: If transceiver is stopped, associated with an m= section
|
||||
// and the associated m= section is rejected in
|
||||
// connection.[[CurrentLocalDescription]] or
|
||||
// connection.[[CurrentRemoteDescription]], remove the
|
||||
// transceiver from the connection's set of transceivers.
|
||||
if (!transceiver->stopped()) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
const ContentInfo* local_content =
|
||||
@ -1730,9 +1701,9 @@ void PeerConnection::RemoveStoppedTransceivers() {
|
||||
(remote_content && remote_content->rejected)) {
|
||||
RTC_LOG(LS_INFO) << "Dissociating transceiver"
|
||||
<< " since the media section is being recycled.";
|
||||
(*it)->internal()->set_mid(absl::nullopt);
|
||||
(*it)->internal()->set_mline_index(absl::nullopt);
|
||||
it = transceivers_.erase(it);
|
||||
transceiver->internal()->set_mid(absl::nullopt);
|
||||
transceiver->internal()->set_mline_index(absl::nullopt);
|
||||
transceivers_.Remove(transceiver);
|
||||
continue;
|
||||
}
|
||||
if (!local_content && !remote_content) {
|
||||
@ -1740,10 +1711,9 @@ void PeerConnection::RemoveStoppedTransceivers() {
|
||||
// See https://github.com/w3c/webrtc-pc/issues/2576
|
||||
RTC_LOG(LS_INFO)
|
||||
<< "Dropping stopped transceiver that was never associated";
|
||||
it = transceivers_.erase(it);
|
||||
transceivers_.Remove(transceiver);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1855,24 +1825,14 @@ rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
PeerConnection::GetAssociatedTransceiver(const std::string& mid) const {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
RTC_DCHECK(IsUnifiedPlan());
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->mid() == mid) {
|
||||
return transceiver;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return transceivers_.FindByMid(mid);
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
PeerConnection::GetTransceiverByMLineIndex(size_t mline_index) const {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
RTC_DCHECK(IsUnifiedPlan());
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->internal()->mline_index() == mline_index) {
|
||||
return transceiver;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return transceivers_.FindByMLineIndex(mline_index);
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
@ -1885,7 +1845,7 @@ PeerConnection::FindAvailableTransceiverToReceive(
|
||||
// the same type that were added to the PeerConnection by addTrack and are not
|
||||
// associated with any m= section and are not stopped, find the first such
|
||||
// RtpTransceiver.
|
||||
for (auto transceiver : transceivers_) {
|
||||
for (auto transceiver : transceivers_.List()) {
|
||||
if (transceiver->media_type() == media_type &&
|
||||
transceiver->internal()->created_by_addtrack() && !transceiver->mid() &&
|
||||
!transceiver->stopped()) {
|
||||
@ -2053,7 +2013,7 @@ RTCError PeerConnection::SetConfiguration(
|
||||
|
||||
if (modified_config.allow_codec_switching.has_value()) {
|
||||
std::vector<cricket::VideoMediaChannel*> channels;
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
if (transceiver->media_type() != cricket::MEDIA_TYPE_VIDEO)
|
||||
continue;
|
||||
|
||||
@ -2184,7 +2144,7 @@ PeerConnection::GetRemoteAudioSSLCertChain() {
|
||||
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
PeerConnection::GetFirstAudioTransceiver() const {
|
||||
for (auto transceiver : transceivers_) {
|
||||
for (auto transceiver : transceivers_.List()) {
|
||||
if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
|
||||
return transceiver;
|
||||
}
|
||||
@ -2308,7 +2268,7 @@ void PeerConnection::Close() {
|
||||
|
||||
NoteUsageEvent(UsageEvent::CLOSE_CALLED);
|
||||
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
transceiver->internal()->SetPeerConnectionClosed();
|
||||
if (!transceiver->stopped())
|
||||
transceiver->StopInternal();
|
||||
@ -3028,7 +2988,7 @@ void PeerConnection::GetOptionsForUnifiedPlanOffer(
|
||||
// and not associated). Reuse media sections marked as recyclable first,
|
||||
// otherwise append to the end of the offer. New media sections should be
|
||||
// added in the order they were added to the PeerConnection.
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
if (transceiver->mid() || transceiver->stopping()) {
|
||||
continue;
|
||||
}
|
||||
@ -3550,7 +3510,7 @@ PeerConnection::GetAudioTransceiver() const {
|
||||
// This method only works with Plan B SDP, where there is a single
|
||||
// audio/video transceiver.
|
||||
RTC_DCHECK(!IsUnifiedPlan());
|
||||
for (auto transceiver : transceivers_) {
|
||||
for (auto transceiver : transceivers_.List()) {
|
||||
if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
|
||||
return transceiver;
|
||||
}
|
||||
@ -3564,7 +3524,7 @@ PeerConnection::GetVideoTransceiver() const {
|
||||
// This method only works with Plan B SDP, where there is a single
|
||||
// audio/video transceiver.
|
||||
RTC_DCHECK(!IsUnifiedPlan());
|
||||
for (auto transceiver : transceivers_) {
|
||||
for (auto transceiver : transceivers_.List()) {
|
||||
if (transceiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
|
||||
return transceiver;
|
||||
}
|
||||
@ -3575,7 +3535,7 @@ PeerConnection::GetVideoTransceiver() const {
|
||||
|
||||
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>>
|
||||
PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) const {
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
for (auto sender : transceiver->internal()->senders()) {
|
||||
if (sender->track() == track) {
|
||||
return sender;
|
||||
@ -3587,7 +3547,7 @@ PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) const {
|
||||
|
||||
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>>
|
||||
PeerConnection::FindSenderById(const std::string& sender_id) const {
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
for (auto sender : transceiver->internal()->senders()) {
|
||||
if (sender->id() == sender_id) {
|
||||
return sender;
|
||||
@ -3599,7 +3559,7 @@ PeerConnection::FindSenderById(const std::string& sender_id) const {
|
||||
|
||||
rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
|
||||
PeerConnection::FindReceiverById(const std::string& receiver_id) const {
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
for (auto receiver : transceiver->internal()->receivers()) {
|
||||
if (receiver->id() == receiver_id) {
|
||||
return receiver;
|
||||
@ -3764,7 +3724,7 @@ void PeerConnection::StopRtcEventLog_w() {
|
||||
|
||||
cricket::ChannelInterface* PeerConnection::GetChannel(
|
||||
const std::string& content_name) {
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
if (channel && channel->content_name() == content_name) {
|
||||
return channel;
|
||||
@ -3873,7 +3833,7 @@ void PeerConnection::UpdatePayloadTypeDemuxingState(
|
||||
// single Invoke; necessary due to thread guards.
|
||||
std::vector<std::pair<RtpTransceiverDirection, cricket::ChannelInterface*>>
|
||||
channels_to_update;
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
const ContentInfo* content =
|
||||
FindMediaSectionForTransceiver(transceiver, sdesc);
|
||||
@ -3923,7 +3883,7 @@ RTCError PeerConnection::PushdownMediaDescription(
|
||||
UpdatePayloadTypeDemuxingState(source);
|
||||
|
||||
// Push down the new SDP media section for each audio/video transceiver.
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
const ContentInfo* content_info =
|
||||
FindMediaSectionForTransceiver(transceiver, sdesc);
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
@ -4099,7 +4059,7 @@ std::map<std::string, std::string> PeerConnection::GetTransportNamesByMid()
|
||||
const {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
std::map<std::string, std::string> transport_names_by_mid;
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
if (channel) {
|
||||
transport_names_by_mid[channel->content_name()] =
|
||||
@ -4278,7 +4238,7 @@ void PeerConnection::OnTransportControllerDtlsHandshakeError(
|
||||
|
||||
void PeerConnection::EnableSending() {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
if (channel && !channel->enabled()) {
|
||||
channel->Enable(true);
|
||||
@ -4848,7 +4808,7 @@ void PeerConnection::OnTransportControllerGatheringState(
|
||||
void PeerConnection::ReportTransportStats() {
|
||||
std::map<std::string, std::set<cricket::MediaType>>
|
||||
media_types_by_transport_name;
|
||||
for (const auto& transceiver : transceivers_) {
|
||||
for (const auto& transceiver : transceivers_.List()) {
|
||||
if (transceiver->internal()->channel()) {
|
||||
const std::string& transport_name =
|
||||
transceiver->internal()->channel()->transport_name();
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
#include "pc/sdp_offer_answer.h"
|
||||
#include "pc/stats_collector.h"
|
||||
#include "pc/stream_collection.h"
|
||||
#include "pc/transceiver_list.h"
|
||||
#include "pc/webrtc_session_description_factory.h"
|
||||
#include "rtc_base/experiments/field_trial_parser.h"
|
||||
#include "rtc_base/operations_chain.h"
|
||||
@ -288,7 +289,7 @@ class PeerConnection : public PeerConnectionInternal,
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
|
||||
GetTransceiversInternal() const override {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
return transceivers_;
|
||||
return transceivers_.List();
|
||||
}
|
||||
|
||||
sigslot::signal1<RtpDataChannel*>& SignalRtpDataChannelCreated() override {
|
||||
@ -400,37 +401,6 @@ class PeerConnection : public PeerConnectionInternal,
|
||||
uint32_t first_ssrc;
|
||||
};
|
||||
|
||||
// Captures partial state to be used for rollback. Applicable only in
|
||||
// Unified Plan.
|
||||
class TransceiverStableState {
|
||||
public:
|
||||
TransceiverStableState() {}
|
||||
void set_newly_created();
|
||||
void SetMSectionIfUnset(absl::optional<std::string> mid,
|
||||
absl::optional<size_t> mline_index);
|
||||
void SetRemoteStreamIdsIfUnset(const std::vector<std::string>& ids);
|
||||
absl::optional<std::string> mid() const { return mid_; }
|
||||
absl::optional<size_t> mline_index() const { return mline_index_; }
|
||||
absl::optional<std::vector<std::string>> remote_stream_ids() const {
|
||||
return remote_stream_ids_;
|
||||
}
|
||||
bool has_m_section() const { return has_m_section_; }
|
||||
bool newly_created() const { return newly_created_; }
|
||||
|
||||
private:
|
||||
absl::optional<std::string> mid_;
|
||||
absl::optional<size_t> mline_index_;
|
||||
absl::optional<std::vector<std::string>> remote_stream_ids_;
|
||||
// Indicates that mid value from stable state has been captured and
|
||||
// that rollback has to restore the transceiver. Also protects against
|
||||
// subsequent overwrites.
|
||||
bool has_m_section_ = false;
|
||||
// Indicates that the transceiver was created as part of applying a
|
||||
// description to track potential need for removing transceiver during
|
||||
// rollback.
|
||||
bool newly_created_ = false;
|
||||
};
|
||||
|
||||
// Implements MessageHandler.
|
||||
void OnMessage(rtc::Message* msg) override;
|
||||
|
||||
@ -1135,22 +1105,10 @@ class PeerConnection : public PeerConnectionInternal,
|
||||
RTC_GUARDED_BY(signaling_thread()); // A pointer is passed to senders_
|
||||
rtc::scoped_refptr<RTCStatsCollector> stats_collector_
|
||||
RTC_GUARDED_BY(signaling_thread());
|
||||
// Holds changes made to transceivers during applying descriptors for
|
||||
// potential rollback. Gets cleared once signaling state goes to stable.
|
||||
std::map<rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>,
|
||||
TransceiverStableState>
|
||||
transceiver_stable_states_by_transceivers_;
|
||||
// Used when rolling back RTP data channels.
|
||||
bool have_pending_rtp_data_channel_ RTC_GUARDED_BY(signaling_thread()) =
|
||||
false;
|
||||
// Holds remote stream ids for transceivers from stable state.
|
||||
std::map<rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>,
|
||||
std::vector<std::string>>
|
||||
remote_stream_ids_by_transceivers_;
|
||||
std::vector<
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
|
||||
transceivers_; // TODO(bugs.webrtc.org/9987): Accessed on both signaling
|
||||
// and network thread.
|
||||
TransceiverList transceivers_;
|
||||
|
||||
// MIDs will be generated using this generator which will keep track of
|
||||
// all the MIDs that have been seen over the life of the PeerConnection.
|
||||
|
||||
@ -946,7 +946,7 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription(
|
||||
}
|
||||
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remove_list;
|
||||
std::vector<rtc::scoped_refptr<MediaStreamInterface>> removed_streams;
|
||||
for (const auto& transceiver : pc_->transceivers_) {
|
||||
for (const auto& transceiver : pc_->transceivers_.List()) {
|
||||
if (transceiver->stopped()) {
|
||||
continue;
|
||||
}
|
||||
@ -1036,7 +1036,7 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription(
|
||||
}
|
||||
|
||||
if (IsUnifiedPlan()) {
|
||||
for (const auto& transceiver : pc_->transceivers_) {
|
||||
for (const auto& transceiver : pc_->transceivers_.List()) {
|
||||
if (transceiver->stopped()) {
|
||||
continue;
|
||||
}
|
||||
@ -1315,7 +1315,7 @@ RTCError SdpOfferAnswerHandler::ApplyRemoteDescription(
|
||||
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remove_list;
|
||||
std::vector<rtc::scoped_refptr<MediaStreamInterface>> added_streams;
|
||||
std::vector<rtc::scoped_refptr<MediaStreamInterface>> removed_streams;
|
||||
for (const auto& transceiver : pc_->transceivers_) {
|
||||
for (const auto& transceiver : pc_->transceivers_.List()) {
|
||||
const ContentInfo* content = pc_->FindMediaSectionForTransceiver(
|
||||
transceiver, remote_description());
|
||||
if (!content) {
|
||||
@ -1334,8 +1334,8 @@ RTCError SdpOfferAnswerHandler::ApplyRemoteDescription(
|
||||
// The remote description has signaled the stream IDs.
|
||||
stream_ids = media_desc->streams()[0].stream_ids();
|
||||
}
|
||||
pc_->transceiver_stable_states_by_transceivers_[transceiver]
|
||||
.SetRemoteStreamIdsIfUnset(transceiver->receiver()->stream_ids());
|
||||
pc_->transceivers_.StableState(transceiver)
|
||||
->SetRemoteStreamIdsIfUnset(transceiver->receiver()->stream_ids());
|
||||
|
||||
RTC_LOG(LS_INFO) << "Processing the MSIDs for MID=" << content->name
|
||||
<< " (" << GetStreamIdsString(stream_ids) << ").";
|
||||
@ -2142,7 +2142,7 @@ RTCError SdpOfferAnswerHandler::UpdateSessionState(
|
||||
RTC_DCHECK_RUN_ON(pc_->signaling_thread());
|
||||
RTC_DCHECK(type == SdpType::kAnswer);
|
||||
ChangeSignalingState(PeerConnectionInterface::kStable);
|
||||
pc_->transceiver_stable_states_by_transceivers_.clear();
|
||||
pc_->transceivers_.DiscardStableStates();
|
||||
pc_->have_pending_rtp_data_channel_ = false;
|
||||
}
|
||||
|
||||
@ -2206,7 +2206,7 @@ RTCError SdpOfferAnswerHandler::Rollback(SdpType desc_type) {
|
||||
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> removed_receivers;
|
||||
|
||||
for (auto&& transceivers_stable_state_pair :
|
||||
pc_->transceiver_stable_states_by_transceivers_) {
|
||||
pc_->transceivers_.StableStates()) {
|
||||
auto transceiver = transceivers_stable_state_pair.first;
|
||||
auto state = transceivers_stable_state_pair.second;
|
||||
|
||||
@ -2237,13 +2237,7 @@ RTCError SdpOfferAnswerHandler::Rollback(SdpType desc_type) {
|
||||
if (transceiver->internal()->reused_for_addtrack()) {
|
||||
transceiver->internal()->set_created_by_addtrack(true);
|
||||
} else {
|
||||
int remaining_transceiver_count = 0;
|
||||
for (auto&& t : pc_->transceivers_) {
|
||||
if (t != transceiver) {
|
||||
pc_->transceivers_[remaining_transceiver_count++] = t;
|
||||
}
|
||||
}
|
||||
pc_->transceivers_.resize(remaining_transceiver_count);
|
||||
pc_->transceivers_.Remove(transceiver);
|
||||
}
|
||||
}
|
||||
transceiver->internal()->sender_internal()->set_transport(nullptr);
|
||||
@ -2258,7 +2252,7 @@ RTCError SdpOfferAnswerHandler::Rollback(SdpType desc_type) {
|
||||
pc_->DestroyDataChannelTransport();
|
||||
pc_->have_pending_rtp_data_channel_ = false;
|
||||
}
|
||||
pc_->transceiver_stable_states_by_transceivers_.clear();
|
||||
pc_->transceivers_.DiscardStableStates();
|
||||
}
|
||||
pending_local_description_.reset();
|
||||
pending_remote_description_.reset();
|
||||
@ -2412,7 +2406,7 @@ bool SdpOfferAnswerHandler::CheckIfNegotiationIsNeeded() {
|
||||
|
||||
// 5. For each transceiver in connection's set of transceivers, perform the
|
||||
// following checks:
|
||||
for (const auto& transceiver : pc_->transceivers_) {
|
||||
for (const auto& transceiver : pc_->transceivers_.List()) {
|
||||
const ContentInfo* current_local_msection =
|
||||
FindTransceiverMSection(transceiver.get(), description);
|
||||
|
||||
@ -2791,8 +2785,7 @@ SdpOfferAnswerHandler::AssociateTransceiver(
|
||||
transceiver->internal()->set_direction(
|
||||
RtpTransceiverDirection::kRecvOnly);
|
||||
if (type == SdpType::kOffer) {
|
||||
pc_->transceiver_stable_states_by_transceivers_[transceiver]
|
||||
.set_newly_created();
|
||||
pc_->transceivers_.StableState(transceiver)->set_newly_created();
|
||||
}
|
||||
}
|
||||
// Check if the offer indicated simulcast but the answer rejected it.
|
||||
@ -2831,9 +2824,9 @@ SdpOfferAnswerHandler::AssociateTransceiver(
|
||||
bool state_changes = transceiver->internal()->mid() != content.name ||
|
||||
transceiver->internal()->mline_index() != mline_index;
|
||||
if (state_changes) {
|
||||
pc_->transceiver_stable_states_by_transceivers_[transceiver]
|
||||
.SetMSectionIfUnset(transceiver->internal()->mid(),
|
||||
transceiver->internal()->mline_index());
|
||||
pc_->transceivers_.StableState(transceiver)
|
||||
->SetMSectionIfUnset(transceiver->internal()->mid(),
|
||||
transceiver->internal()->mline_index());
|
||||
}
|
||||
}
|
||||
// Associate the found or created RtpTransceiver with the m= section by
|
||||
|
||||
67
pc/transceiver_list.cc
Normal file
67
pc/transceiver_list.cc
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2020 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "pc/transceiver_list.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
void TransceiverStableState::set_newly_created() {
|
||||
RTC_DCHECK(!has_m_section_);
|
||||
newly_created_ = true;
|
||||
}
|
||||
|
||||
void TransceiverStableState::SetMSectionIfUnset(
|
||||
absl::optional<std::string> mid,
|
||||
absl::optional<size_t> mline_index) {
|
||||
if (!has_m_section_) {
|
||||
mid_ = mid;
|
||||
mline_index_ = mline_index;
|
||||
has_m_section_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TransceiverStableState::SetRemoteStreamIdsIfUnset(
|
||||
const std::vector<std::string>& ids) {
|
||||
if (!remote_stream_ids_.has_value()) {
|
||||
remote_stream_ids_ = ids;
|
||||
}
|
||||
}
|
||||
|
||||
RtpTransceiverProxyRefPtr TransceiverList::FindBySender(
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender) const {
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->sender() == sender) {
|
||||
return transceiver;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RtpTransceiverProxyRefPtr TransceiverList::FindByMid(
|
||||
const std::string& mid) const {
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->mid() == mid) {
|
||||
return transceiver;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RtpTransceiverProxyRefPtr TransceiverList::FindByMLineIndex(
|
||||
size_t mline_index) const {
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->internal()->mline_index() == mline_index) {
|
||||
return transceiver;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
100
pc/transceiver_list.h
Normal file
100
pc/transceiver_list.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2020 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef PC_TRANSCEIVER_LIST_H_
|
||||
#define PC_TRANSCEIVER_LIST_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pc/rtp_transceiver.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
typedef rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
RtpTransceiverProxyRefPtr;
|
||||
|
||||
// Captures partial state to be used for rollback. Applicable only in
|
||||
// Unified Plan.
|
||||
class TransceiverStableState {
|
||||
public:
|
||||
TransceiverStableState() {}
|
||||
void set_newly_created();
|
||||
void SetMSectionIfUnset(absl::optional<std::string> mid,
|
||||
absl::optional<size_t> mline_index);
|
||||
void SetRemoteStreamIdsIfUnset(const std::vector<std::string>& ids);
|
||||
absl::optional<std::string> mid() const { return mid_; }
|
||||
absl::optional<size_t> mline_index() const { return mline_index_; }
|
||||
absl::optional<std::vector<std::string>> remote_stream_ids() const {
|
||||
return remote_stream_ids_;
|
||||
}
|
||||
bool has_m_section() const { return has_m_section_; }
|
||||
bool newly_created() const { return newly_created_; }
|
||||
|
||||
private:
|
||||
absl::optional<std::string> mid_;
|
||||
absl::optional<size_t> mline_index_;
|
||||
absl::optional<std::vector<std::string>> remote_stream_ids_;
|
||||
// Indicates that mid value from stable state has been captured and
|
||||
// that rollback has to restore the transceiver. Also protects against
|
||||
// subsequent overwrites.
|
||||
bool has_m_section_ = false;
|
||||
// Indicates that the transceiver was created as part of applying a
|
||||
// description to track potential need for removing transceiver during
|
||||
// rollback.
|
||||
bool newly_created_ = false;
|
||||
};
|
||||
|
||||
class TransceiverList {
|
||||
public:
|
||||
std::vector<RtpTransceiverProxyRefPtr> List() const { return transceivers_; }
|
||||
|
||||
void Add(RtpTransceiverProxyRefPtr transceiver) {
|
||||
transceivers_.push_back(transceiver);
|
||||
}
|
||||
void Remove(RtpTransceiverProxyRefPtr transceiver) {
|
||||
transceivers_.erase(
|
||||
std::remove(transceivers_.begin(), transceivers_.end(), transceiver),
|
||||
transceivers_.end());
|
||||
}
|
||||
RtpTransceiverProxyRefPtr FindBySender(
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender) const;
|
||||
RtpTransceiverProxyRefPtr FindByMid(const std::string& mid) const;
|
||||
RtpTransceiverProxyRefPtr FindByMLineIndex(size_t mline_index) const;
|
||||
|
||||
// Find or create the stable state for a transceiver.
|
||||
TransceiverStableState* StableState(RtpTransceiverProxyRefPtr transceiver) {
|
||||
return &(transceiver_stable_states_by_transceivers_[transceiver]);
|
||||
}
|
||||
|
||||
void DiscardStableStates() {
|
||||
transceiver_stable_states_by_transceivers_.clear();
|
||||
}
|
||||
|
||||
std::map<RtpTransceiverProxyRefPtr, TransceiverStableState>& StableStates() {
|
||||
return transceiver_stable_states_by_transceivers_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<RtpTransceiverProxyRefPtr> transceivers_;
|
||||
// Holds changes made to transceivers during applying descriptors for
|
||||
// potential rollback. Gets cleared once signaling state goes to stable.
|
||||
std::map<RtpTransceiverProxyRefPtr, TransceiverStableState>
|
||||
transceiver_stable_states_by_transceivers_;
|
||||
// Holds remote stream ids for transceivers from stable state.
|
||||
std::map<RtpTransceiverProxyRefPtr, std::vector<std::string>>
|
||||
remote_stream_ids_by_transceivers_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TRANSCEIVER_LIST_H_
|
||||
Loading…
x
Reference in New Issue
Block a user