Add threading assertions to TransceiverList
Also add a function for accessing the list as internal transceivers rather than accessing the proxy objects; this exposes where the internal objects are accessed and where we need external references. Used the new list function in sdp_offer_answer wherever possible. Adds an UnsafeList function that is not thread guarded, so that the job of rooting out those instances can be done in a later CL. Bug: webrtc:12692 Change-Id: Ia591f22a1c8f82ec452a1a66a94fbf9ab9debd14 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215581 Commit-Queue: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Tommi <tommi@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33781}
This commit is contained in:
parent
dcac9fe3d1
commit
8546666cb9
@ -454,7 +454,10 @@ rtc_library("transceiver_list") {
|
||||
"../api:rtc_error",
|
||||
"../api:rtp_parameters",
|
||||
"../api:scoped_refptr",
|
||||
"../api:sequence_checker",
|
||||
"../rtc_base:checks",
|
||||
"../rtc_base:macromagic",
|
||||
"../rtc_base/system:no_unique_address",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
}
|
||||
|
||||
@ -41,13 +41,13 @@
|
||||
#include "p2p/base/p2p_constants.h"
|
||||
#include "p2p/base/p2p_transport_channel.h"
|
||||
#include "p2p/base/transport_info.h"
|
||||
#include "pc/channel.h"
|
||||
#include "pc/ice_server_parsing.h"
|
||||
#include "pc/rtp_receiver.h"
|
||||
#include "pc/rtp_sender.h"
|
||||
#include "pc/sctp_transport.h"
|
||||
#include "pc/simulcast_description.h"
|
||||
#include "pc/webrtc_session_description_factory.h"
|
||||
#include "rtc_base/callback_list.h"
|
||||
#include "rtc_base/helpers.h"
|
||||
#include "rtc_base/ip_address.h"
|
||||
#include "rtc_base/location.h"
|
||||
@ -2084,8 +2084,7 @@ void PeerConnection::StopRtcEventLog_w() {
|
||||
|
||||
cricket::ChannelInterface* PeerConnection::GetChannel(
|
||||
const std::string& content_name) {
|
||||
RTC_DCHECK_RUN_ON(network_thread());
|
||||
for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
|
||||
for (const auto& transceiver : rtp_manager()->transceivers()->UnsafeList()) {
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
if (channel && channel->content_name() == content_name) {
|
||||
return channel;
|
||||
@ -2636,7 +2635,7 @@ void PeerConnection::ReportTransportStats() {
|
||||
rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
|
||||
std::map<std::string, std::set<cricket::MediaType>>
|
||||
media_types_by_transport_name;
|
||||
for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
|
||||
for (const auto& transceiver : rtp_manager()->transceivers()->UnsafeList()) {
|
||||
if (transceiver->internal()->channel()) {
|
||||
const std::string& transport_name =
|
||||
transceiver->internal()->channel()->transport_name();
|
||||
|
||||
@ -97,6 +97,7 @@
|
||||
#include "rtc_base/thread.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
#include "rtc_base/unique_id_generator.h"
|
||||
#include "rtc_base/weak_ptr.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -428,7 +429,8 @@ class PeerConnection : public PeerConnectionInternal,
|
||||
bool SetupDataChannelTransport_n(const std::string& mid)
|
||||
RTC_RUN_ON(network_thread());
|
||||
void TeardownDataChannelTransport_n() RTC_RUN_ON(network_thread());
|
||||
cricket::ChannelInterface* GetChannel(const std::string& content_name);
|
||||
cricket::ChannelInterface* GetChannel(const std::string& content_name)
|
||||
RTC_RUN_ON(network_thread());
|
||||
|
||||
// Functions made public for testing.
|
||||
void ReturnHistogramVeryQuicklyForTesting() {
|
||||
|
||||
@ -141,7 +141,10 @@ RtpTransceiver::RtpTransceiver(
|
||||
}
|
||||
|
||||
RtpTransceiver::~RtpTransceiver() {
|
||||
StopInternal();
|
||||
if (!stopped_) {
|
||||
RTC_DCHECK_RUN_ON(thread_);
|
||||
StopInternal();
|
||||
}
|
||||
}
|
||||
|
||||
void RtpTransceiver::SetChannel(cricket::ChannelInterface* channel) {
|
||||
@ -401,6 +404,7 @@ RTCError RtpTransceiver::StopStandard() {
|
||||
}
|
||||
|
||||
void RtpTransceiver::StopInternal() {
|
||||
RTC_DCHECK_RUN_ON(thread_);
|
||||
StopTransceiverProcedure();
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/crypto/crypto_options.h"
|
||||
#include "api/data_channel_interface.h"
|
||||
#include "api/dtls_transport_interface.h"
|
||||
#include "api/media_stream_proxy.h"
|
||||
#include "api/rtp_parameters.h"
|
||||
@ -32,6 +31,7 @@
|
||||
#include "media/base/codec.h"
|
||||
#include "media/base/media_engine.h"
|
||||
#include "media/base/rid_description.h"
|
||||
#include "p2p/base/ice_transport_internal.h"
|
||||
#include "p2p/base/p2p_constants.h"
|
||||
#include "p2p/base/p2p_transport_channel.h"
|
||||
#include "p2p/base/port.h"
|
||||
@ -39,14 +39,13 @@
|
||||
#include "p2p/base/transport_description_factory.h"
|
||||
#include "p2p/base/transport_info.h"
|
||||
#include "pc/data_channel_utils.h"
|
||||
#include "pc/media_protocol_names.h"
|
||||
#include "pc/dtls_transport.h"
|
||||
#include "pc/media_stream.h"
|
||||
#include "pc/peer_connection.h"
|
||||
#include "pc/peer_connection_message_handler.h"
|
||||
#include "pc/rtp_media_utils.h"
|
||||
#include "pc/rtp_sender.h"
|
||||
#include "pc/rtp_transport_internal.h"
|
||||
#include "pc/sctp_transport.h"
|
||||
#include "pc/simulcast_description.h"
|
||||
#include "pc/stats_collector.h"
|
||||
#include "pc/usage_pattern.h"
|
||||
@ -56,7 +55,6 @@
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/ref_counted_object.h"
|
||||
#include "rtc_base/rtc_certificate.h"
|
||||
#include "rtc_base/socket_address.h"
|
||||
#include "rtc_base/ssl_stream_adapter.h"
|
||||
#include "rtc_base/string_encode.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
@ -249,7 +247,7 @@ void ReportSimulcastApiVersion(const char* name,
|
||||
}
|
||||
|
||||
const ContentInfo* FindTransceiverMSection(
|
||||
RtpTransceiverProxyWithInternal<RtpTransceiver>* transceiver,
|
||||
RtpTransceiver* transceiver,
|
||||
const SessionDescriptionInterface* session_description) {
|
||||
return transceiver->mid()
|
||||
? session_description->description()->GetContentByName(
|
||||
@ -419,7 +417,7 @@ bool VerifyIceUfragPwdPresent(const SessionDescription* desc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static RTCError ValidateMids(const cricket::SessionDescription& description) {
|
||||
RTCError ValidateMids(const cricket::SessionDescription& description) {
|
||||
std::set<std::string> mids;
|
||||
for (const cricket::ContentInfo& content : description.contents()) {
|
||||
if (content.name.empty()) {
|
||||
@ -471,7 +469,7 @@ std::string GetSignalingStateString(
|
||||
// This method will extract any send encodings that were sent by the remote
|
||||
// connection. This is currently only relevant for Simulcast scenario (where
|
||||
// the number of layers may be communicated by the server).
|
||||
static std::vector<RtpEncodingParameters> GetSendEncodingsFromRemoteDescription(
|
||||
std::vector<RtpEncodingParameters> GetSendEncodingsFromRemoteDescription(
|
||||
const MediaContentDescription& desc) {
|
||||
if (!desc.HasSimulcast()) {
|
||||
return {};
|
||||
@ -495,7 +493,7 @@ static std::vector<RtpEncodingParameters> GetSendEncodingsFromRemoteDescription(
|
||||
return result;
|
||||
}
|
||||
|
||||
static RTCError UpdateSimulcastLayerStatusInSender(
|
||||
RTCError UpdateSimulcastLayerStatusInSender(
|
||||
const std::vector<SimulcastLayer>& layers,
|
||||
rtc::scoped_refptr<RtpSenderInternal> sender) {
|
||||
RTC_DCHECK(sender);
|
||||
@ -526,9 +524,8 @@ static RTCError UpdateSimulcastLayerStatusInSender(
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool SimulcastIsRejected(
|
||||
const ContentInfo* local_content,
|
||||
const MediaContentDescription& answer_media_desc) {
|
||||
bool SimulcastIsRejected(const ContentInfo* local_content,
|
||||
const MediaContentDescription& answer_media_desc) {
|
||||
bool simulcast_offered = local_content &&
|
||||
local_content->media_description() &&
|
||||
local_content->media_description()->HasSimulcast();
|
||||
@ -538,7 +535,7 @@ static bool SimulcastIsRejected(
|
||||
return simulcast_offered && (!simulcast_answered || !rids_supported);
|
||||
}
|
||||
|
||||
static RTCError DisableSimulcastInSender(
|
||||
RTCError DisableSimulcastInSender(
|
||||
rtc::scoped_refptr<RtpSenderInternal> sender) {
|
||||
RTC_DCHECK(sender);
|
||||
RtpParameters parameters = sender->GetParametersInternal();
|
||||
@ -556,7 +553,7 @@ static RTCError DisableSimulcastInSender(
|
||||
|
||||
// The SDP parser used to populate these values by default for the 'content
|
||||
// name' if an a=mid line was absent.
|
||||
static absl::string_view GetDefaultMidForPlanB(cricket::MediaType media_type) {
|
||||
absl::string_view GetDefaultMidForPlanB(cricket::MediaType media_type) {
|
||||
switch (media_type) {
|
||||
case cricket::MEDIA_TYPE_AUDIO:
|
||||
return cricket::CN_AUDIO;
|
||||
@ -595,10 +592,8 @@ void AddPlanBRtpSenderOptions(
|
||||
}
|
||||
}
|
||||
|
||||
static cricket::MediaDescriptionOptions
|
||||
GetMediaDescriptionOptionsForTransceiver(
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
transceiver,
|
||||
cricket::MediaDescriptionOptions GetMediaDescriptionOptionsForTransceiver(
|
||||
RtpTransceiver* transceiver,
|
||||
const std::string& mid,
|
||||
bool is_create_offer) {
|
||||
// NOTE: a stopping transceiver should be treated as a stopped one in
|
||||
@ -618,7 +613,7 @@ GetMediaDescriptionOptionsForTransceiver(
|
||||
// 2. If the MSID is included, then it must be included in any subsequent
|
||||
// offer/answer exactly the same until the RtpTransceiver is stopped.
|
||||
if (stopped || (!RtpTransceiverDirectionHasSend(transceiver->direction()) &&
|
||||
!transceiver->internal()->has_ever_been_used_to_send())) {
|
||||
!transceiver->has_ever_been_used_to_send())) {
|
||||
return media_description_options;
|
||||
}
|
||||
|
||||
@ -629,7 +624,7 @@ GetMediaDescriptionOptionsForTransceiver(
|
||||
// The following sets up RIDs and Simulcast.
|
||||
// RIDs are included if Simulcast is requested or if any RID was specified.
|
||||
RtpParameters send_parameters =
|
||||
transceiver->internal()->sender_internal()->GetParametersInternal();
|
||||
transceiver->sender_internal()->GetParametersInternal();
|
||||
bool has_rids = std::any_of(send_parameters.encodings.begin(),
|
||||
send_parameters.encodings.end(),
|
||||
[](const RtpEncodingParameters& encoding) {
|
||||
@ -661,9 +656,8 @@ GetMediaDescriptionOptionsForTransceiver(
|
||||
}
|
||||
|
||||
// Returns the ContentInfo at mline index |i|, or null if none exists.
|
||||
static const ContentInfo* GetContentByIndex(
|
||||
const SessionDescriptionInterface* sdesc,
|
||||
size_t i) {
|
||||
const ContentInfo* GetContentByIndex(const SessionDescriptionInterface* sdesc,
|
||||
size_t i) {
|
||||
if (!sdesc) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1291,7 +1285,8 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription(
|
||||
}
|
||||
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remove_list;
|
||||
std::vector<rtc::scoped_refptr<MediaStreamInterface>> removed_streams;
|
||||
for (const auto& transceiver : transceivers()->List()) {
|
||||
for (const auto& transceiver_ext : transceivers()->List()) {
|
||||
auto transceiver = transceiver_ext->internal();
|
||||
if (transceiver->stopped()) {
|
||||
continue;
|
||||
}
|
||||
@ -1302,10 +1297,8 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription(
|
||||
if (transceiver->mid()) {
|
||||
auto dtls_transport = LookupDtlsTransportByMid(
|
||||
pc_->network_thread(), transport_controller(), *transceiver->mid());
|
||||
transceiver->internal()->sender_internal()->set_transport(
|
||||
dtls_transport);
|
||||
transceiver->internal()->receiver_internal()->set_transport(
|
||||
dtls_transport);
|
||||
transceiver->sender_internal()->set_transport(dtls_transport);
|
||||
transceiver->receiver_internal()->set_transport(dtls_transport);
|
||||
}
|
||||
|
||||
const ContentInfo* content =
|
||||
@ -1322,16 +1315,15 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription(
|
||||
// "recvonly", process the removal of a remote track for the media
|
||||
// description, given transceiver, removeList, and muteTracks.
|
||||
if (!RtpTransceiverDirectionHasRecv(media_desc->direction()) &&
|
||||
(transceiver->internal()->fired_direction() &&
|
||||
RtpTransceiverDirectionHasRecv(
|
||||
*transceiver->internal()->fired_direction()))) {
|
||||
ProcessRemovalOfRemoteTrack(transceiver, &remove_list,
|
||||
(transceiver->fired_direction() &&
|
||||
RtpTransceiverDirectionHasRecv(*transceiver->fired_direction()))) {
|
||||
ProcessRemovalOfRemoteTrack(transceiver_ext, &remove_list,
|
||||
&removed_streams);
|
||||
}
|
||||
// 2.2.7.1.6.2: Set transceiver's [[CurrentDirection]] and
|
||||
// [[FiredDirection]] slots to direction.
|
||||
transceiver->internal()->set_current_direction(media_desc->direction());
|
||||
transceiver->internal()->set_fired_direction(media_desc->direction());
|
||||
transceiver->set_current_direction(media_desc->direction());
|
||||
transceiver->set_fired_direction(media_desc->direction());
|
||||
}
|
||||
}
|
||||
auto observer = pc_->Observer();
|
||||
@ -1380,7 +1372,10 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription(
|
||||
}
|
||||
|
||||
if (IsUnifiedPlan()) {
|
||||
for (const auto& transceiver : transceivers()->List()) {
|
||||
// We must use List and not ListInternal here because
|
||||
// transceivers()->StableState() is indexed by the non-internal refptr.
|
||||
for (const auto& transceiver_ext : transceivers()->List()) {
|
||||
auto transceiver = transceiver_ext->internal();
|
||||
if (transceiver->stopped()) {
|
||||
continue;
|
||||
}
|
||||
@ -1389,25 +1384,22 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription(
|
||||
if (!content) {
|
||||
continue;
|
||||
}
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
cricket::ChannelInterface* channel = transceiver->channel();
|
||||
if (content->rejected || !channel || channel->local_streams().empty()) {
|
||||
// 0 is a special value meaning "this sender has no associated send
|
||||
// stream". Need to call this so the sender won't attempt to configure
|
||||
// a no longer existing stream and run into DCHECKs in the lower
|
||||
// layers.
|
||||
transceiver->internal()->sender_internal()->SetSsrc(0);
|
||||
transceiver->sender_internal()->SetSsrc(0);
|
||||
} else {
|
||||
// Get the StreamParams from the channel which could generate SSRCs.
|
||||
const std::vector<StreamParams>& streams = channel->local_streams();
|
||||
transceiver->internal()->sender_internal()->set_stream_ids(
|
||||
streams[0].stream_ids());
|
||||
auto encodings =
|
||||
transceiver->internal()->sender_internal()->init_send_encodings();
|
||||
transceiver->internal()->sender_internal()->SetSsrc(
|
||||
streams[0].first_ssrc());
|
||||
transceiver->sender_internal()->set_stream_ids(streams[0].stream_ids());
|
||||
auto encodings = transceiver->sender_internal()->init_send_encodings();
|
||||
transceiver->sender_internal()->SetSsrc(streams[0].first_ssrc());
|
||||
if (!encodings.empty()) {
|
||||
transceivers()
|
||||
->StableState(transceiver)
|
||||
->StableState(transceiver_ext)
|
||||
->SetInitSendEncodings(encodings);
|
||||
}
|
||||
}
|
||||
@ -1654,7 +1646,8 @@ 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 : transceivers()->List()) {
|
||||
for (const auto& transceiver_ext : transceivers()->List()) {
|
||||
const auto transceiver = transceiver_ext->internal();
|
||||
const ContentInfo* content =
|
||||
FindMediaSectionForTransceiver(transceiver, remote_description());
|
||||
if (!content) {
|
||||
@ -1674,14 +1667,13 @@ RTCError SdpOfferAnswerHandler::ApplyRemoteDescription(
|
||||
stream_ids = media_desc->streams()[0].stream_ids();
|
||||
}
|
||||
transceivers()
|
||||
->StableState(transceiver)
|
||||
->StableState(transceiver_ext)
|
||||
->SetRemoteStreamIdsIfUnset(transceiver->receiver()->stream_ids());
|
||||
|
||||
RTC_LOG(LS_INFO) << "Processing the MSIDs for MID=" << content->name
|
||||
<< " (" << GetStreamIdsString(stream_ids) << ").";
|
||||
SetAssociatedRemoteStreams(transceiver->internal()->receiver_internal(),
|
||||
stream_ids, &added_streams,
|
||||
&removed_streams);
|
||||
SetAssociatedRemoteStreams(transceiver->receiver_internal(), stream_ids,
|
||||
&added_streams, &removed_streams);
|
||||
// From the WebRTC specification, steps 2.2.8.5/6 of section 4.4.1.6
|
||||
// "Set the RTCSessionDescription: If direction is sendrecv or recvonly,
|
||||
// and transceiver's current direction is neither sendrecv nor recvonly,
|
||||
@ -1701,26 +1693,24 @@ RTCError SdpOfferAnswerHandler::ApplyRemoteDescription(
|
||||
if (!RtpTransceiverDirectionHasRecv(local_direction) &&
|
||||
(transceiver->fired_direction() &&
|
||||
RtpTransceiverDirectionHasRecv(*transceiver->fired_direction()))) {
|
||||
ProcessRemovalOfRemoteTrack(transceiver, &remove_list,
|
||||
ProcessRemovalOfRemoteTrack(transceiver_ext, &remove_list,
|
||||
&removed_streams);
|
||||
}
|
||||
// 2.2.8.1.10: Set transceiver's [[FiredDirection]] slot to direction.
|
||||
transceiver->internal()->set_fired_direction(local_direction);
|
||||
transceiver->set_fired_direction(local_direction);
|
||||
// 2.2.8.1.11: If description is of type "answer" or "pranswer", then run
|
||||
// the following steps:
|
||||
if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
|
||||
// 2.2.8.1.11.1: Set transceiver's [[CurrentDirection]] slot to
|
||||
// direction.
|
||||
transceiver->internal()->set_current_direction(local_direction);
|
||||
transceiver->set_current_direction(local_direction);
|
||||
// 2.2.8.1.11.[3-6]: Set the transport internal slots.
|
||||
if (transceiver->mid()) {
|
||||
auto dtls_transport = LookupDtlsTransportByMid(pc_->network_thread(),
|
||||
transport_controller(),
|
||||
*transceiver->mid());
|
||||
transceiver->internal()->sender_internal()->set_transport(
|
||||
dtls_transport);
|
||||
transceiver->internal()->receiver_internal()->set_transport(
|
||||
dtls_transport);
|
||||
transceiver->sender_internal()->set_transport(dtls_transport);
|
||||
transceiver->receiver_internal()->set_transport(dtls_transport);
|
||||
}
|
||||
}
|
||||
// 2.2.8.1.12: If the media description is rejected, and transceiver is
|
||||
@ -1728,18 +1718,16 @@ RTCError SdpOfferAnswerHandler::ApplyRemoteDescription(
|
||||
if (content->rejected && !transceiver->stopped()) {
|
||||
RTC_LOG(LS_INFO) << "Stopping transceiver for MID=" << content->name
|
||||
<< " since the media section was rejected.";
|
||||
transceiver->internal()->StopTransceiverProcedure();
|
||||
transceiver->StopTransceiverProcedure();
|
||||
}
|
||||
if (!content->rejected &&
|
||||
RtpTransceiverDirectionHasRecv(local_direction)) {
|
||||
if (!media_desc->streams().empty() &&
|
||||
media_desc->streams()[0].has_ssrcs()) {
|
||||
uint32_t ssrc = media_desc->streams()[0].first_ssrc();
|
||||
transceiver->internal()->receiver_internal()->SetupMediaChannel(ssrc);
|
||||
transceiver->receiver_internal()->SetupMediaChannel(ssrc);
|
||||
} else {
|
||||
transceiver->internal()
|
||||
->receiver_internal()
|
||||
->SetupUnsignaledMediaChannel();
|
||||
transceiver->receiver_internal()->SetupUnsignaledMediaChannel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2859,12 +2847,12 @@ bool SdpOfferAnswerHandler::CheckIfNegotiationIsNeeded() {
|
||||
|
||||
// 5. For each transceiver in connection's set of transceivers, perform the
|
||||
// following checks:
|
||||
for (const auto& transceiver : transceivers()->List()) {
|
||||
for (const auto& transceiver : transceivers()->ListInternal()) {
|
||||
const ContentInfo* current_local_msection =
|
||||
FindTransceiverMSection(transceiver.get(), description);
|
||||
FindTransceiverMSection(transceiver, description);
|
||||
|
||||
const ContentInfo* current_remote_msection = FindTransceiverMSection(
|
||||
transceiver.get(), current_remote_description());
|
||||
const ContentInfo* current_remote_msection =
|
||||
FindTransceiverMSection(transceiver, current_remote_description());
|
||||
|
||||
// 5.4 If transceiver is stopped and is associated with an m= section,
|
||||
// but the associated m= section is not yet rejected in
|
||||
@ -2952,7 +2940,7 @@ bool SdpOfferAnswerHandler::CheckIfNegotiationIsNeeded() {
|
||||
return true;
|
||||
|
||||
const ContentInfo* offered_remote_msection =
|
||||
FindTransceiverMSection(transceiver.get(), remote_description());
|
||||
FindTransceiverMSection(transceiver, remote_description());
|
||||
|
||||
RtpTransceiverDirection offered_direction =
|
||||
offered_remote_msection
|
||||
@ -3456,19 +3444,17 @@ SdpOfferAnswerHandler::FindAvailableTransceiverToReceive(
|
||||
|
||||
const cricket::ContentInfo*
|
||||
SdpOfferAnswerHandler::FindMediaSectionForTransceiver(
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
transceiver,
|
||||
const RtpTransceiver* transceiver,
|
||||
const SessionDescriptionInterface* sdesc) const {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
RTC_DCHECK(transceiver);
|
||||
RTC_DCHECK(sdesc);
|
||||
if (IsUnifiedPlan()) {
|
||||
if (!transceiver->internal()->mid()) {
|
||||
if (!transceiver->mid()) {
|
||||
// This transceiver is not associated with a media section yet.
|
||||
return nullptr;
|
||||
}
|
||||
return sdesc->description()->GetContentByName(
|
||||
*transceiver->internal()->mid());
|
||||
return sdesc->description()->GetContentByName(*transceiver->mid());
|
||||
} else {
|
||||
// Plan B only allows at most one audio and one video section, so use the
|
||||
// first media section of that type.
|
||||
@ -3665,7 +3651,7 @@ void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanOffer(
|
||||
} else {
|
||||
session_options->media_description_options.push_back(
|
||||
GetMediaDescriptionOptionsForTransceiver(
|
||||
transceiver, mid,
|
||||
transceiver->internal(), mid,
|
||||
/*is_create_offer=*/true));
|
||||
// CreateOffer shouldn't really cause any state changes in
|
||||
// PeerConnection, but we need a way to match new transceivers to new
|
||||
@ -3703,7 +3689,7 @@ void SdpOfferAnswerHandler::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()->List()) {
|
||||
for (const auto& transceiver : transceivers()->ListInternal()) {
|
||||
if (transceiver->mid() || transceiver->stopping()) {
|
||||
continue;
|
||||
}
|
||||
@ -3723,7 +3709,7 @@ void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanOffer(
|
||||
/*is_create_offer=*/true));
|
||||
}
|
||||
// See comment above for why CreateOffer changes the transceiver's state.
|
||||
transceiver->internal()->set_mline_index(mline_index);
|
||||
transceiver->set_mline_index(mline_index);
|
||||
}
|
||||
// Lastly, add a m-section if we have local data channels and an m section
|
||||
// does not already exist.
|
||||
@ -3826,7 +3812,7 @@ void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanAnswer(
|
||||
if (transceiver) {
|
||||
session_options->media_description_options.push_back(
|
||||
GetMediaDescriptionOptionsForTransceiver(
|
||||
transceiver, content.name,
|
||||
transceiver->internal(), content.name,
|
||||
/*is_create_offer=*/false));
|
||||
} else {
|
||||
// This should only happen with rejected transceivers.
|
||||
@ -4149,8 +4135,8 @@ void SdpOfferAnswerHandler::UpdateRemoteSendersList(
|
||||
|
||||
void SdpOfferAnswerHandler::EnableSending() {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
for (const auto& transceiver : transceivers()->List()) {
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
for (const auto& transceiver : transceivers()->ListInternal()) {
|
||||
cricket::ChannelInterface* channel = transceiver->channel();
|
||||
if (channel && !channel->enabled()) {
|
||||
channel->Enable(true);
|
||||
}
|
||||
@ -4175,10 +4161,10 @@ RTCError SdpOfferAnswerHandler::PushdownMediaDescription(
|
||||
}
|
||||
|
||||
// Push down the new SDP media section for each audio/video transceiver.
|
||||
for (const auto& transceiver : transceivers()->List()) {
|
||||
for (const auto& transceiver : transceivers()->ListInternal()) {
|
||||
const ContentInfo* content_info =
|
||||
FindMediaSectionForTransceiver(transceiver, sdesc);
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
cricket::ChannelInterface* channel = transceiver->channel();
|
||||
if (!channel || !content_info || content_info->rejected) {
|
||||
continue;
|
||||
}
|
||||
@ -4258,10 +4244,10 @@ void SdpOfferAnswerHandler::RemoveStoppedTransceivers() {
|
||||
if (!transceiver->stopped()) {
|
||||
continue;
|
||||
}
|
||||
const ContentInfo* local_content =
|
||||
FindMediaSectionForTransceiver(transceiver, local_description());
|
||||
const ContentInfo* remote_content =
|
||||
FindMediaSectionForTransceiver(transceiver, remote_description());
|
||||
const ContentInfo* local_content = FindMediaSectionForTransceiver(
|
||||
transceiver->internal(), local_description());
|
||||
const ContentInfo* remote_content = FindMediaSectionForTransceiver(
|
||||
transceiver->internal(), remote_description());
|
||||
if ((local_content && local_content->rejected) ||
|
||||
(remote_content && remote_content->rejected)) {
|
||||
RTC_LOG(LS_INFO) << "Dissociating transceiver"
|
||||
@ -4824,8 +4810,8 @@ bool SdpOfferAnswerHandler::UpdatePayloadTypeDemuxingState(
|
||||
// single Invoke; necessary due to thread guards.
|
||||
std::vector<std::pair<RtpTransceiverDirection, cricket::ChannelInterface*>>
|
||||
channels_to_update;
|
||||
for (const auto& transceiver : transceivers()->List()) {
|
||||
cricket::ChannelInterface* channel = transceiver->internal()->channel();
|
||||
for (const auto& transceiver : transceivers()->ListInternal()) {
|
||||
cricket::ChannelInterface* channel = transceiver->channel();
|
||||
const ContentInfo* content =
|
||||
FindMediaSectionForTransceiver(transceiver, sdesc);
|
||||
if (!channel || !content) {
|
||||
@ -4836,8 +4822,7 @@ bool SdpOfferAnswerHandler::UpdatePayloadTypeDemuxingState(
|
||||
if (source == cricket::CS_REMOTE) {
|
||||
local_direction = RtpTransceiverDirectionReversed(local_direction);
|
||||
}
|
||||
channels_to_update.emplace_back(local_direction,
|
||||
transceiver->internal()->channel());
|
||||
channels_to_update.emplace_back(local_direction, transceiver->channel());
|
||||
}
|
||||
|
||||
if (channels_to_update.empty()) {
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@ -175,15 +174,6 @@ class SdpOfferAnswerHandler : public SdpStateProvider,
|
||||
bool HasNewIceCredentials();
|
||||
void UpdateNegotiationNeeded();
|
||||
|
||||
// Returns the media section in the given session description that is
|
||||
// associated with the RtpTransceiver. Returns null if none found or this
|
||||
// RtpTransceiver is not associated. Logic varies depending on the
|
||||
// SdpSemantics specified in the configuration.
|
||||
const cricket::ContentInfo* FindMediaSectionForTransceiver(
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
transceiver,
|
||||
const SessionDescriptionInterface* sdesc) const;
|
||||
|
||||
// Destroys all BaseChannels and destroys the SCTP data channel, if present.
|
||||
void DestroyAllChannels();
|
||||
|
||||
@ -319,6 +309,14 @@ class SdpOfferAnswerHandler : public SdpStateProvider,
|
||||
const cricket::ContentInfo* old_remote_content)
|
||||
RTC_RUN_ON(signaling_thread());
|
||||
|
||||
// Returns the media section in the given session description that is
|
||||
// associated with the RtpTransceiver. Returns null if none found or this
|
||||
// RtpTransceiver is not associated. Logic varies depending on the
|
||||
// SdpSemantics specified in the configuration.
|
||||
const cricket::ContentInfo* FindMediaSectionForTransceiver(
|
||||
const RtpTransceiver* transceiver,
|
||||
const SessionDescriptionInterface* sdesc) const;
|
||||
|
||||
// If the BUNDLE policy is max-bundle, then we know for sure that all
|
||||
// transports will be bundled from the start. This method returns the BUNDLE
|
||||
// group if that's the case, or null if BUNDLE will be negotiated later. An
|
||||
@ -420,7 +418,7 @@ class SdpOfferAnswerHandler : public SdpStateProvider,
|
||||
// |removed_streams| is the list of streams which no longer have a receiving
|
||||
// track so should be removed.
|
||||
void ProcessRemovalOfRemoteTrack(
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
const rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
transceiver,
|
||||
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>* remove_list,
|
||||
std::vector<rtc::scoped_refptr<MediaStreamInterface>>* removed_streams);
|
||||
|
||||
@ -41,8 +41,18 @@ void TransceiverStableState::SetInitSendEncodings(
|
||||
init_send_encodings_ = encodings;
|
||||
}
|
||||
|
||||
std::vector<RtpTransceiver*> TransceiverList::ListInternal() const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
std::vector<RtpTransceiver*> internals;
|
||||
for (auto transceiver : transceivers_) {
|
||||
internals.push_back(transceiver->internal());
|
||||
}
|
||||
return internals;
|
||||
}
|
||||
|
||||
RtpTransceiverProxyRefPtr TransceiverList::FindBySender(
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender) const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->sender() == sender) {
|
||||
return transceiver;
|
||||
@ -53,6 +63,7 @@ RtpTransceiverProxyRefPtr TransceiverList::FindBySender(
|
||||
|
||||
RtpTransceiverProxyRefPtr TransceiverList::FindByMid(
|
||||
const std::string& mid) const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->mid() == mid) {
|
||||
return transceiver;
|
||||
@ -63,6 +74,7 @@ RtpTransceiverProxyRefPtr TransceiverList::FindByMid(
|
||||
|
||||
RtpTransceiverProxyRefPtr TransceiverList::FindByMLineIndex(
|
||||
size_t mline_index) const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->internal()->mline_index() == mline_index) {
|
||||
return transceiver;
|
||||
|
||||
@ -21,9 +21,14 @@
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/media_types.h"
|
||||
#include "api/rtc_error.h"
|
||||
#include "api/rtp_parameters.h"
|
||||
#include "api/rtp_sender_interface.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "api/sequence_checker.h"
|
||||
#include "pc/rtp_transceiver.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/system/no_unique_address.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -68,14 +73,36 @@ class TransceiverStableState {
|
||||
bool newly_created_ = false;
|
||||
};
|
||||
|
||||
// This class encapsulates the active list of transceivers on a
|
||||
// PeerConnection, and offers convenient functions on that list.
|
||||
// It is a single-thread class; all operations must be performed
|
||||
// on the same thread.
|
||||
class TransceiverList {
|
||||
public:
|
||||
std::vector<RtpTransceiverProxyRefPtr> List() const { return transceivers_; }
|
||||
// Returns a copy of the currently active list of transceivers. The
|
||||
// list consists of rtc::scoped_refptrs, which will keep the transceivers
|
||||
// from being deallocated, even if they are removed from the TransceiverList.
|
||||
std::vector<RtpTransceiverProxyRefPtr> List() const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
return transceivers_;
|
||||
}
|
||||
// As above, but does not check thread ownership. Unsafe.
|
||||
// TODO(bugs.webrtc.org/12692): Refactor and remove
|
||||
std::vector<RtpTransceiverProxyRefPtr> UnsafeList() const {
|
||||
return transceivers_;
|
||||
}
|
||||
|
||||
// Returns a list of the internal() pointers of the currently active list
|
||||
// of transceivers. These raw pointers are not thread-safe, so need to
|
||||
// be consumed on the same thread.
|
||||
std::vector<RtpTransceiver*> ListInternal() const;
|
||||
|
||||
void Add(RtpTransceiverProxyRefPtr transceiver) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
transceivers_.push_back(transceiver);
|
||||
}
|
||||
void Remove(RtpTransceiverProxyRefPtr transceiver) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
transceivers_.erase(
|
||||
std::remove(transceivers_.begin(), transceivers_.end(), transceiver),
|
||||
transceivers_.end());
|
||||
@ -87,26 +114,33 @@ class TransceiverList {
|
||||
|
||||
// Find or create the stable state for a transceiver.
|
||||
TransceiverStableState* StableState(RtpTransceiverProxyRefPtr transceiver) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
return &(transceiver_stable_states_by_transceivers_[transceiver]);
|
||||
}
|
||||
|
||||
void DiscardStableStates() {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
transceiver_stable_states_by_transceivers_.clear();
|
||||
}
|
||||
|
||||
std::map<RtpTransceiverProxyRefPtr, TransceiverStableState>& StableStates() {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
return transceiver_stable_states_by_transceivers_;
|
||||
}
|
||||
|
||||
private:
|
||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||
std::vector<RtpTransceiverProxyRefPtr> transceivers_;
|
||||
// TODO(bugs.webrtc.org/12692): Add RTC_GUARDED_BY(sequence_checker_);
|
||||
|
||||
// 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_;
|
||||
transceiver_stable_states_by_transceivers_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
// Holds remote stream ids for transceivers from stable state.
|
||||
std::map<RtpTransceiverProxyRefPtr, std::vector<std::string>>
|
||||
remote_stream_ids_by_transceivers_;
|
||||
remote_stream_ids_by_transceivers_ RTC_GUARDED_BY(sequence_checker_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user